I have C/C++ SDK library which should be ported to Windows 8 Metro (WinRT). Library is mostly OS-independent, but it contains some modules which interact with hardware using OS-provided APIs.
While porting it to WinRT I've decided to try to use WRL instead of C++/CX as much as possible. So right now I can create and consume most of the required WinRT objects. But I've faced absolute obstacle while working with Async objects, provided by WinRT.
For example, I use following code to enumerate HW devices:
// 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);
At this point I have valid IAsyncOperation pointer. I thought it can be used like that:
task<ComPtr<DeviceInformationCollection*>> tsk(operation);
but I failed, because task<> constructor which accepts IAsyncOperation is declared under "#if defined(__cplusplus_winrt)" in ppltasks.h, which, in turn, depends on /ZW compiler option.
How I'm supposed to use IAsyncOperation object in this case? Actually, I only need to wait for operation to be completed.
Just in case someone else is looking for this in C++/WinRT:
auto asyncOp = someFunctionReturningIAsyncOperation();
asyncOp.Completed([](auto &&result, auto && status) {
// do whatever with result and status
});
From my C++/CX experience, what you can do is you can construct an AsyncOperationCompletedHandler<DeviceInformationCollection*>
object, initialize it with a member function in your class, and assign it to the Completed
property of the IAsyncOperation.
In C++/CX, you just construct the AsyncOperationCompletedHandler<>
object with two parameters - this
from the calling class, and a pointer-to-member to a callback method. Like this:
MyAsyncOp->Completed = ref new AsyncOperationCompletedHandler<ResultType ^>(this, &MyClass::OnDone);
where OnDone is defined thus:
void MyClass::OnDone(IAsyncOperation<ResultType ^> ^AsOp, AsyncStatus s)
{
ResultType ^Result = AsOp->GetResults();
}
I'm not sure how to call constructors in WRL. You figure this one out.
Also, the completion handler will be called on a random thread. If you need to pass something back to the UI thread, Dispatcher->RunAsync()
is your friend. Most XAML classes have a Dispatcher member in them.
EDIT: now that I'm looking at samples, there seems to be a non-managed helper class called Callback
that you construct around a this
and a pointer-to-member. Look it up. Still not sure how to connect one to an IAsyncOperation though...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With