C++/WinRT中如何设置GattSession.MaintainConnection属性
开发环境
- IDE:Visual Studio 2019
- 运行系统:Windows 10
- Windows SDK版本:10.0.18363.0
- 平台工具集:v142
问题背景
无C#开发基础,因调用Win10 API实现蓝牙BLE功能接触WinRT,参考开源WinBle项目POC做二次开发,过程中遇到GattSession相关接口调用编译报错,涉及两个核心疑问。
已尝试的代码与报错
- 蓝牙广播Watcher初始化(本地名称筛选写法存在问题)
// Create watcher BluetoothLEAdvertisementWatcher watcher; // fill in watcher filter watcher.AdvertisementFilter().Advertisement().LocalName().c_str() == L"DomasG9630"; - 按蓝牙地址获取BLE设备对象
调用后auto device = co_await BluetoothLEDevice::FromBluetoothAddressAsync(deviceAddress);device.ConnectionStatus()返回Disconnected,查阅文档得知需要设置GattSession.MaintainConnection为true才会主动发起连接,但编写代码时持续出现编译错误。 - 错误的静态属性调用写法
// 报错:非静态成员引用必须与特定对象实例关联 GenericAttributeProfile::GattSession::MaintainConnection(true); - 按服务UUID获取GATT服务
GUID DomasMainServiceGuid = { 0x0000fff0, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }; auto services = co_await device.GetGattServicesForUuidAsync(DomasMainServiceGuid); - 错误的GattSession构造传参
// 报错:不存在从winrt::hstring到const winrt::Windows::Devices::Bluetooth::BluetoothDeviceId的合适类型转换 auto connect = co_await GenericAttributeProfile::GattSession::FromDeviceIdAsync(device.DeviceId())
问题解答
1. 获取FromDeviceIdAsync所需BluetoothDeviceId类型参数的方法
GattSession::FromDeviceIdAsync不接受hstring类型的原始设备ID字符串作为入参,需要先通过设备ID字符串构造BluetoothDeviceId类实例,写法如下:
// 从BLE设备对象获取ID字符串,构造符合参数要求的BluetoothDeviceId实例 winrt::Windows::Devices::Bluetooth::BluetoothDeviceId targetBleDeviceId(device.DeviceId()); // 传入构造好的参数获取GattSession实例 auto gattSession = co_await winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::GattSession::FromDeviceIdAsync(targetBleDeviceId);
2. GattSession实例设置MaintainConnection属性的正确写法
之前编译报错的核心原因是MaintainConnection是GattSession实例的非静态可写属性,不是类的静态方法,不能直接通过类名调用。拿到有效GattSession实例后,直接对实例的属性赋值即可:
if (gattSession != nullptr) { // 给实例属性赋值为true,触发系统维护BLE连接 gattSession.MaintainConnection(true); // 可选:注册会话状态变化回调,方便跟踪连接状态 gattSession.SessionStatusChanged([](const auto& sender, const auto& args) { auto currentStatus = args.Status(); // 自行添加状态处理逻辑 }); }
补充修正:你之前写的广播Watcher本地名称筛选代码无效,
==只是做了临时的字符串比较,没有给过滤器属性赋值,正确写法为:BluetoothLEAdvertisementWatcher watcher; // 直接给LocalName属性赋值目标设备名称 watcher.AdvertisementFilter().Advertisement().LocalName(L"DomasG9630");
内容的提问来源于stack exchange,提问作者ehardin
相关产品推荐
相关产品推荐

