3

我有应该移植到 Windows 8 Metro (WinRT) 的 C/C++ SDK 库。库大部分是独立于操作系统的,但它包含一些使用操作系统提供的 API 与硬件交互的模块。

在将其移植到 WinRT 时,我决定尽可能使用 WRL 而不是 C++/CX。所以现在我可以创建和使用大部分必需的 WinRT 对象。但是在使用由 WinRT 提供的异步对象时,我遇到了绝对的障碍。

例如,我使用以下代码枚举硬件设备:

// 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)”下声明,而这又取决于 /ZW 编译器选项。

在这种情况下,我应该如何使用 IAsyncOperation 对象?实际上,我只需要等待操作完成。

4

5 回答 5

4

以防万一其他人在 C++/WinRT 中寻找这个:

    auto asyncOp = someFunctionReturningIAsyncOperation();

    asyncOp.Completed([](auto &&result, auto && status) {
        // do whatever with result and status
    });
于 2018-08-30T07:05:09.483 回答
1

根据我的 C++/CX 经验,您可以构造一个AsyncOperationCompletedHandler<DeviceInformationCollection*>对象,使用类中的成员函数对其进行初始化,并将其分配给CompletedIAsyncOperation 的属性。

在 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您围绕 athis和指向成员的指针构建的。查一下。仍然不确定如何将一个连接到 IAsyncOperation...

于 2012-07-10T17:37:19.450 回答
1

这是一个老问题......但如果有人像我一样需要答案:

MSDN 文档展示了如何在本机 C++ 中完成此操作。这很简单。您初始化 WRL 运行时,即您感兴趣的对象,然后创建一个事件和回调处理程序,该处理程序将在事件触发时被调用。

于 2015-01-20T18:10:04.933 回答
0

如果硬件特定模块已经在 Win32 上运行,我建议你保持这种方式。安装一个 Win32 服务与硬件交互,然后 Metro 应用只需要与服务进行通信(许多 IPC 选项,例如套接字、管道,我相信即使在受限的 Metro 沙箱中你也能找到一个也能正常工作的)。

于 2012-07-10T17:20:03.783 回答
-1

IAsyncOperation 是一种可等待类型,因此您应该使用 await 的等价物,或者将其称为 Result 属性。

于 2013-03-20T21:27:16.480 回答