使用Windows BluetoothLEApis设置BLE特征值遇问题求助
BLE特征值设置问题:结构体设计解析与代码错误修正
一、_BTH_LE_GATT_CHARACTERISTIC_VALUE结构体设计原因
这个结构体采用的是C语言柔性数组的兼容实现方案:
- 早期C标准(C99之前)没有正式的柔性数组语法,因此用单元素数组
UCHAR Data[1]模拟,配合_Field_size_bytes_(DataSize)标注,告诉编译器Data数组的实际有效长度由DataSize指定。 - MIDL中的
UCHAR Data[*]是标准柔性数组声明,用于接口定义。
这种设计的优势:
- 无需额外指针成员,减少内存开销(避免指针本身的存储空间,以及两次内存分配的成本)
- 结构体与数据连续存储,缓存访问效率更高
- 降低内存碎片风险,一次分配即可容纳结构体与所有数据
二、你的代码错误修正
当前代码存在两个核心问题:
- 数据未完整赋值:仅给
Data[0]赋值,DataSize却设为3,剩余字节为随机值,导致发送数据异常 - 栈内存越界:栈上声明的结构体
Data数组仅1个元素,直接访问Data[1]/Data[2]属于未定义行为,会引发内存错误
正确实现方式(动态分配内存,推荐)
unsigned char ClearAxisZ[] = { 0xff,0xaa,0x52 }; // 计算总内存:结构体大小 + 数据大小 - 1(减去Data[1]的默认1字节) size_t totalSize = sizeof(BTH_LE_GATT_CHARACTERISTIC_VALUE) + sizeof(ClearAxisZ) - 1; // 动态分配内存 PBTH_LE_GATT_CHARACTERISTIC_VALUE pValue = (PBTH_LE_GATT_CHARACTERISTIC_VALUE)malloc(totalSize); if (pValue == NULL) { // 处理内存分配失败逻辑 return; } // 初始化结构体与数据 pValue->DataSize = sizeof(ClearAxisZ); memcpy(pValue->Data, ClearAxisZ, sizeof(ClearAxisZ)); // 调用BLE设置API HRESULT hr = BluetoothGATTSetCharacteristicValue( Device, Characteristices + CharacteristicIndex, pValue, NULL, BLUETOOTH_GATT_FLAG_WRITE_WITHOUT_RESPONSE ); // 释放内存 free(pValue);
备选方案(固定大小栈内存,仅适用于数据长度固定的场景)
// 定义包含足够数据空间的嵌套结构体 typedef struct { BTH_LE_GATT_CHARACTERISTIC_VALUE base; UCHAR extraData[2]; // 补充2字节,使总数据容量达到3 } CHAR_VALUE_3BYTES; unsigned char ClearAxisZ[] = { 0xff,0xaa,0x52 }; CHAR_VALUE_3BYTES Value = {0}; Value.base.DataSize = 3; memcpy(Value.base.Data, ClearAxisZ, 3); BluetoothGATTSetCharacteristicValue( Device, Characteristices + CharacteristicIndex, &Value.base, NULL, BLUETOOTH_GATT_FLAG_WRITE_WITHOUT_RESPONSE );
内容的提问来源于stack exchange,提问作者梁海濤
相关产品推荐
相关产品推荐

