我有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);
但我失败了,因为任务&lt;&gt;接受IAsyncOperation的构造函数在ppltasks.h中的“#if defined(__ cplusplus_winrt)”下声明,而ppltasks.h依赖于/ ZW编译器选项。
在这种情况下,我应该如何使用IAsyncOperation对象?实际上,我只需要等待操作完成。
答案 0 :(得分:3)
以防万一其他人正在C ++ / WinRT中寻找它:
auto asyncOp = someFunctionReturningIAsyncOperation();
asyncOp.Completed([](auto &&result, auto && status) {
// do whatever with result and status
});
答案 1 :(得分:1)
根据我的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但是......
答案 2 :(得分:1)
这是一个老问题......但是如果有人像我一样需要答案:
MSDN documentation显示了如何在本机C ++中完成此任务。这很简单。您初始化WRL运行时,您感兴趣的对象,然后创建一个事件和回调处理程序,将在事件触发时调用。
答案 3 :(得分:0)
如果库特定于硬件的模块已在Win32上运行,我建议您保持这种方式。安装Win32服务以与硬件交互,然后Metro应用程序只需要与服务进行通信(许多IPC选项,例如套接字,管道,我相信即使在受限制的Metro沙箱中也能找到一个运行良好的选项)。
答案 4 :(得分:-1)
IAsyncOperation是一个等待类型,所以你应该使用等效的await,或者调用它的Result属性。