C#调用Win32 API注册GATT特征值变更通知遇0x57错误求助
排查C#调用
BluetoothGATTRegisterEvent返回0x57(E_INVALIDARG)错误的建议 我正尝试通过C#调用Win32 API注册GATT特征值变更通知,已成功获取设备句柄、相关GATT服务及特征。但调用BluetoothGATTRegisterEvent时始终返回0x57(E_INVALIDARG)错误,且无明确无效参数提示。尝试过更换第一个参数为设备句柄或特征的ServiceHandle等多种参数组合,均无效。以下是调用该API所用的结构体定义及代码(服务与特征发现部分功能正常,已省略):
public enum BTH_LE_GATT_EVENT_TYPE { CharacteristicValueChangedEvent = 0 } [StructLayout(LayoutKind.Sequential)] public struct BLUETOOTH_GATT_NOTIFICATION_REGISTRATION { public ushort NumCharacteristics; public BTH_LE_GATT_CHARACTERISTIC[] Characteristics; } [StructLayout(LayoutKind.Sequential)] public struct BLUETOOTH_GATT_EVENT_HANDLE { public IntPtr handle; } // Define the callback delegate internal delegate void PFNBLUETOOTH_GATT_EVENT_CALLBACK( BTH_LE_GATT_EVENT_TYPE EventType, IntPtr EventOutParameter, IntPtr Context ); [DllImport("BluetoothApis.dll", SetLastError = true)] public static extern uint BluetoothGATTRegisterEvent( ushort Service, BTH_LE_GATT_EVENT_TYPE eventType, ref BLUETOOTH_GATT_NOTIFICATION_REGISTRATION eventParameterIn, PFNBLUETOOTH_GATT_EVENT_CALLBACK callback, IntPtr context, ref BLUETOOTH_GATT_EVENT_HANDLE eventHandle, uint Flags ); public void RegisterEvents( SafeFileHandle deviceHandle, BTH_LE_GATT_SERVICE service, BTH_LE_GATT_CHARACTERISTIC characteristic, PFNBLUETOOTH_GATT_EVENT_CALLBACK eventHandler ) { var eventHandle = new BLUETOOTH_GATT_EVENT_HANDLE(); var eventParameters = new BLUETOOTH_GATT_NOTIFICATION_REGISTRATION { NumCharacteristics = 1, Characteristics = new[] { characteristic } }; BluetoothGATTRegisterEvent( characteristic.ServiceHandle, BTH_LE_GATT_EVENT_TYPE.CharacteristicValueChangedEvent, ref eventParameters, eventHandler, IntPtr.Zero, ref eventHandle, BLUETOOTH_GATT_FLAG_NONE ); }
问题排查建议
- 修正参数类型:
BluetoothGATTRegisterEvent的第一个参数Service应为IntPtr(对应Win32的HANDLE类型),当前定义为ushort会导致参数长度不匹配,这是触发E_INVALIDARG的高概率原因。 - 调整结构体数组的封送方式:
BLUETOOTH_GATT_NOTIFICATION_REGISTRATION中的Characteristics数组需要添加[MarshalAs(UnmanagedType.LPArray)]特性,否则非托管代码无法正确识别数组指针,修改后的结构体定义如下:[StructLayout(LayoutKind.Sequential)] public struct BLUETOOTH_GATT_NOTIFICATION_REGISTRATION { public ushort NumCharacteristics; [MarshalAs(UnmanagedType.LPArray)] public BTH_LE_GATT_CHARACTERISTIC[] Characteristics; } - 指定回调委托的调用约定:在
PFNBLUETOOTH_GATT_EVENT_CALLBACK委托上添加[UnmanagedFunctionPointer(CallingConvention.StdCall)]特性,确保与Win32 API的调用约定一致:[UnmanagedFunctionPointer(CallingConvention.StdCall)] internal delegate void PFNBLUETOOTH_GATT_EVENT_CALLBACK( BTH_LE_GATT_EVENT_TYPE EventType, IntPtr EventOutParameter, IntPtr Context ); - 校验特征属性:确认目标特征的
CharacteristicProperties包含CharacteristicNotify或CharacteristicIndicate标志,API不允许为不支持通知/指示的特征注册事件。 - 检查句柄有效性:再次确认
characteristic.ServiceHandle是有效的GATT服务句柄,避免因类型转换导致句柄值被截断或篡改。 - 验证Flags参数:确保
BLUETOOTH_GATT_FLAG_NONE的常量值为0,与Win32定义一致。
内容的提问来源于stack exchange,提问作者Morten Lemvigh
相关产品推荐
相关产品推荐

