如何在“native c ++”环境中使用WinRT IAsyncOperation *对象
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在“native c ++”环境中使用WinRT IAsyncOperation *对象相关的知识,希望对你有一定的参考价值。
我有C / C ++ SDK库,应该移植到Windows 8 Metro(WinRT)。库主要与操作系统无关,但它包含一些使用操作系统提供的API与硬件交互的模块。
在将其移植到WinRT时,我决定尝试尽可能多地使用WRL而不是C ++ / CX。所以现在我可以创建和使用大多数所需的WinRT对象。但是,在使用WinRT提供的Async对象时,我遇到了绝对的障碍。
例如,我使用以下代码枚举HW设备:
// create interface to "static" members of DeviceInformation class
ComPtr<IDeviceInformationStatics> DeviceInformationStatics;
HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation).Get(), &DeviceInformationStatics);
ComPtr<IAsyncOperation<DeviceInformationCollection*>> operation;
hr = DeviceInformationStatics->FindAllAsyncDeviceClass( DeviceClass_All, &operation);
此时我有有效的IAsyncOperation指针。我认为它可以这样使用:
task<ComPtr<DeviceInformationCollection*>> tsk(operation);
但是我失败了,因为接受IAsyncOperation的task <>构造函数在ppltasks.h中的“#if defined(__ cplusplus_winrt)”下声明,而ppltasks.h依赖于/ ZW编译器选项。
在这种情况下我应该如何使用IAsyncOperation对象?实际上,我只需要等待操作完成。
以防其他人在C ++ / WinRT中寻找这个:
auto asyncOp = someFunctionReturningIAsyncOperation();
asyncOp.Completed([](auto &&result, auto && status) {
// do whatever with result and status
});
根据我的C ++ / CX经验,您可以做的是构建一个AsyncOperationCompletedHandler<DeviceInformationCollection*>
对象,使用类中的成员函数对其进行初始化,并将其分配给IAsyncOperation的Completed
属性。
在C ++ / CX中,您只需使用两个参数构造AsyncOperationCompletedHandler<>
对象 - 来自调用类的this
,以及指向回调方法的成员指针。像这样:
MyAsyncOp->Completed = ref new AsyncOperationCompletedHandler<ResultType ^>(this, &MyClass::OnDone);
其中OnDone的定义如下:
void MyClass::OnDone(IAsyncOperation<ResultType ^> ^AsOp, AsyncStatus s)
{
ResultType ^Result = AsOp->GetResults();
}
我不确定如何在WRL中调用构造函数。你想出这个。
此外,将在随机线程上调用完成处理程序。如果您需要将某些内容传递回UI线程,Dispatcher->RunAsync()
就是您的朋友。大多数XAML类都包含Dispatcher成员。
编辑:现在我正在查看示例,似乎有一个名为Callback
的非托管辅助类,它围绕this
和指向成员的指针构建。仔细看看。仍然不确定如何将一个连接到IAsyncOperation但是...
这是一个老问题......但是如果有人像我一样需要答案:
MSDN documentation展示了如何在本机C ++中实现这一目标。这很简单。您初始化WRL运行时,您感兴趣的对象,然后创建一个事件和回调处理程序,将在事件触发时调用。
如果 图书馆 特定于硬件的模块已经在Win32上运行,我建议你保持这种方式。安装Win32服务以与硬件交互,然后Metro应用程序只需要与服务进行通信(许多IPC选项,例如套接字,管道,我相信即使在受限制的Metro沙箱中也能找到一个运行良好的选项)。
IAsyncOperation是一个等待类型,因此您应该使用等效的await,或者调用它的Result属性。
以上是关于如何在“native c ++”环境中使用WinRT IAsyncOperation *对象的主要内容,如果未能解决你的问题,请参考以下文章
如何使用给定的 nativeID 识别目标 c 中的视图(在 react-native 中给出)
在 Kotlin Native 中,如何在不使用 C 指针的情况下将对象保留在单独的线程中,并从任何其他线程中改变其状态?