事件似乎从未在一个非常简单的C++ / WinRT控制台应用程序中开火。
用于配置设备
TestDevice
FFFF
EEEE
下面的程序将简单地
TestDevice
TestDevice
ShortID FFFF
查找服务EEEE
查找该服务的特性GattClientCharacteristicConfigurationDescriptorValue
to EEEE
,它具有读、写和通知属性。TypedEventHandler<GattCharacteristic,GattValueChangedEventArgs>
到ValueChanged
,它应该在值更新时打印New Value
。更新特征值不会触发ValueChanged
事件。然而,同样的设备设置已经通过蓝牙堆栈进行了测试,并取得了成功。
#include "pch.h"
#include <iostream>
#include <Windows.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Devices.Bluetooth.h>
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
#include <winrt/Windows.Devices.Bluetooth.Advertisement.h>
using winrt::Windows::Devices::Bluetooth::BluetoothConnectionStatus;
using winrt::Windows::Devices::Bluetooth::BluetoothLEDevice;
using winrt::Windows::Devices::Bluetooth::BluetoothUuidHelper;
using winrt::Windows::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementReceivedEventArgs;
using winrt::Windows::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementWatcher;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Devices::Bluetooth::GenericAttributeProfile;
using namespace winrt;
class WinBleCentral
{
public:
WinBleCentral()
{
bleWatcher.Received(
[this](BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
hstring testHstring{ std::wstring_view(L"TestDevice") };
if (testHstring == eventArgs.Advertisement().LocalName())
{
this->bleWatcher.Stop();
std::cout << "Matched\n";
BluetoothLEDevice::FromBluetoothAddressAsync(eventArgs.BluetoothAddress()).Completed(
[this](IAsyncOperation<BluetoothLEDevice> sender, AsyncStatus status)
{
if (auto device = sender.GetResults(); device)
{
std::cout << "Connected\n";
winrt::guid serviceGUID = BluetoothUuidHelper::FromShortId(0xFFFF);
device.GetGattServicesForUuidAsync(serviceGUID).Completed(
[this](IAsyncOperation<GattDeviceServicesResult> sender, AsyncStatus status)
{
GattDeviceServicesResult result = sender.get();
if (result && status == winrt::Windows::Foundation::AsyncStatus::Completed)
{
winrt::guid charGUID = BluetoothUuidHelper::FromShortId(0xEEEE);
std::cout << "Num Services: " << result.Services().Size() << '\n';
for (auto&& service : result.Services())
{
service.GetCharacteristicsForUuidAsync(charGUID).Completed(
[this](IAsyncOperation<GattCharacteristicsResult>sender, AsyncStatus status)
{
std::cout << "Get Characteristics\n";
if (auto result = sender.GetResults(); result)
{
std::cout << "Num Characteristics: " << result.Characteristics().Size() << '\n';
for (auto character : result.Characteristics())
{
character.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue::Notify).Completed(
[this, character](IAsyncOperation<GattCommunicationStatus>sender, AsyncStatus status)
{
character.ValueChanged([this](GattCharacteristic characteristic, GattValueChangedEventArgs const& args)
{
std::cout << "New Value!\n";
});
});
}
}
});
}
}
}
);
}
});
}
});
bleWatcher.Start();
};
BluetoothLEAdvertisementWatcher bleWatcher;
};
int main()
{
WinBleCentral bleCentral;
while (getchar() != '\n');
}
发布于 2022-02-21 21:53:15
这似乎是由于GattCharacteristic
对象超出了作用域。通过简单地保持对tha变量的引用,上述工作将如愿以偿。
下面是与上面相同的程序,为了提高可读性,去掉了Async
方面的内容。我已经测试过了,在这两种情况下都显示了完全相同的行为。
#include "pch.h"
#include <iostream>
#include <Windows.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Devices.Bluetooth.h>
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
#include <winrt/Windows.Devices.Bluetooth.Advertisement.h>
using winrt::Windows::Devices::Bluetooth::BluetoothConnectionStatus;
using winrt::Windows::Devices::Bluetooth::BluetoothLEDevice;
using winrt::Windows::Devices::Bluetooth::BluetoothUuidHelper;
using winrt::Windows::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementReceivedEventArgs;
using winrt::Windows::Devices::Bluetooth::Advertisement::BluetoothLEAdvertisementWatcher;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::Devices::Bluetooth::GenericAttributeProfile;
using namespace winrt;
class WinBleCentral
{
public:
WinBleCentral()
{
std::cout << "Start\n";
bleWatcher.Received(
[this](BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
hstring testHstring{ std::wstring_view(L"TestDevice") };
if (testHstring == eventArgs.Advertisement().LocalName())
{
this->bleWatcher.Stop();
std::cout << "Matched\n";
auto device = BluetoothLEDevice::FromBluetoothAddressAsync(eventArgs.BluetoothAddress()).get();
std::cout << "Device\n";
winrt::guid serviceGUID = BluetoothUuidHelper::FromShortId(0xFFFF);
auto serviceResults = device.GetGattServicesForUuidAsync(serviceGUID).get();
std::cout << "Service Results\n";
winrt::guid charGUID = BluetoothUuidHelper::FromShortId(0xEEEE);
auto service = serviceResults.Services().GetAt(0);
std::cout << "Services\n";
auto characteristicResults = service.GetCharacteristicsForUuidAsync(charGUID).get();
std::cout << "Characteristic Results\n";
auto characteristic = characteristicResults.Characteristics().GetAt(0);
characteristics.push_back(characteristic);
std::cout << "Characterstic\n";
auto gattCommunicationStatus = characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue::Notify).get();
std::cout << "WriteClientCharacteristicConfiguration\n";
characteristic.ValueChanged([this](GattCharacteristic const& notifyingCharacteristic, GattValueChangedEventArgs args)
{
std::cout << "New Value!\n";
});
}
});
bleWatcher.Start();
}
std::vector<GattCharacteristic> characteristics;
BluetoothLEAdvertisementWatcher bleWatcher;
};
int main()
{
WinBleCentral bleCentral;
while (getchar() != '\n');
}
即使从未使用过std::vector<GattCharacteristic> characteristics
,characteristics.push_back(characteristic)
的简单操作也足以保持引用的活力。这种行为是绝对没有预料到的。
为了保持整个UWP风格,我最初使用了IVector
和Append
方法,但是整个东西在check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector<T>)->Append(impl::bind_in(value)));
上崩溃,看起来是空指针。
针对上述情况,为了提高可读性,避免了所有错误检查。实际实现应该对所有异步操作进行健康检查,以确保数据实际存在。
https://stackoverflow.com/questions/71209738
复制相似问题