如何在“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 指针的情况下将对象保留在单独的线程中,并从任何其他线程中改变其状态?

React native with UWP - 如何设置 react-native UWP 环境?

Kotlin/Native 垃圾收集器如何在 C 中工作?

如何将支付网关部署到真实环境中?

如何使用 Jest 在本机反应中模拟“react-native-config”库的配置数据?