【发布时间】:2019-06-17 11:39:42
【问题描述】:
我正在使用 Windows Sensor API 从各种传感器(包括加速度计和陀螺仪)获取信息。 (https://docs.microsoft.com/en-us/windows/desktop/sensorsapi/sensor-api-programming-guide)
我的加速度计传感器驱动程序的初始实现工作正常 - 我可以异步获取该传感器的值。
单个传感器(加速度计)的工作初始化代码如下所示:
void initialize1(AccelerometerCallBack callBack) {
HRESULT hr = S_OK;
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
ISensorManager* pSensorManager = NULL;
ISensorCollection* pSensorColl = NULL;
ISensor* accelerometer = NULL;
hr = CoCreateInstance(CLSID_SensorManager,
NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pSensorManager));
if (SUCCEEDED(hr))
{
printf("Succeeded getting Sensor...\n");
ULONG ulCount = 0;
// Verify that the collection contains
// at least one sensor.
hr = pSensorColl->GetCount(&ulCount);
if (SUCCEEDED(hr))
{
if (ulCount < 1)
{
wprintf_s(L"\nNo sensors of the requested category.\n");
hr = E_UNEXPECTED;
}
}
}
else {
printf("Failed to get Sensor...\n");
}
if (SUCCEEDED(hr))
{
// Get the first available sensor.
hr = pSensorColl->GetAt(0, &accelerometer);
BSTR name = 0;
hr = accelerometer->GetFriendlyName(&name);
wprintf(L"%s\n", name);
}
AccelerometerEvent* pEventClass = NULL;
ISensorEvents* pMyEvents = NULL;
if (SUCCEEDED(hr))
{
// Create an instance of the event class.
pEventClass = new(std::nothrow) AccelerometerEvent();
pEventClass->globalCallBack = callBack;
}
if (SUCCEEDED(hr))
{
// Retrieve the pointer to the callback interface.
hr = pEventClass->QueryInterface(IID_PPV_ARGS(&pMyEvents));
}
if (SUCCEEDED(hr))
{
// Start receiving events.
hr = accelerometer->SetEventSink(pMyEvents);
}
MSG msg;
BOOL bRet;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
现在我想同时获取陀螺仪,所以我添加了类似的初始化代码:
void initialize2(GyroscopeCallBack callBack);,其作用与上述类似。
现在我的 C# 层会像这样触发这些代码:
internal void Start()
{
AccelerometerCallBack myCallBack1 = new AccelerometerCallBack(onAccelerometerDataChanged);
initialize1(myCallBack1);
GyroscopeCallBack myCallBack2 = new GyroscopeCallBack(onGyroscopeDataChanged);
initialize2(myCallBack2);
}
但是,只有加速度计信息是通过回调接收的,而不是陀螺仪的。
- 我已确认我的设备具有正确类型的两个传感器
- 我已经确认我的回调函数和 C# 到 C++ 接口都可以正常工作
使用 Windows 传感器 API“获取”多个传感器(而不是一个)的正确方法是什么?
官方网站上没有关于这样做的示例,唯一相关的SO帖子(Exposing multiple sensors on a single device to Windows Sensor API)也没有帮助。谢谢!
【问题讨论】:
-
如果只加载陀螺仪,是否有效?尝试使用传感器诊断工具来验证它不是硬件限制。传感器可以一起加载。
-
您所展示的只是创建
ISensorManagerCOM 对象的代码,而不是任何实际使用它的代码,或设置各个传感器及其事件接收器,或处理其事件的代码.请提供一个 minimal reproducible example 来证明您的问题在行动中。 -
代码“在这里做更多”是什么?里面有没有类似
while(true)或其他循环的东西?你能确保程序实际运行到new GyroscopeCallBack()这一行吗? -
@Michael 如果我只加载陀螺仪,它确实可以工作。
-
@JohnW 您根本不应该在传感器初始化函数中调用
CoInitializeEx。这属于您的应用程序启动代码。但主要问题是,您甚至在触摸陀螺仪之前就已经为加速度计完成了所有工作。这很容易解决,只需将代码分解一下即可。创建 1 个 SensorManager,然后为其中的两个传感器设置事件接收器,然后运行消息循环。您的初始化函数不仅仅是初始化,还需要将消息循环从它们中取出并单独处理。