如何在" native c ++"中使用WinRT IAsyncOperation *对象。环境

时间:2012-07-10 17:15:04

标签: c++ asynchronous windows-runtime

我有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对象?实际上,我只需要等待操作完成。

5 个答案:

答案 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属性。