MicrosoftDocs / winrt-related

WinRT related reference content for developing Microsoft Universal Windows Platform (UWP) apps
Creative Commons Attribution 4.0 International
76 stars 91 forks source link

IAsyncOperation array types in MIDL #85

Closed sichbo closed 5 years ago

sichbo commented 5 years ago

Jeez, who's bugging you guys more than me lately, eh? 🙄 So here's something that ostensibly "should" work in MIDL 3.0 but raises a compilation error. A solution/reason why it doesn't work would be great to have in the intro here.

Busted MIDL:

runtimeclass Thing
{
    Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVector<String>> ListThings();
}

Emits:

error MIDL2025: [msg]syntax error [context]: expecting > or , near ">>"
error MIDL2025: [msg]syntax error [context]: expecting > or , near "("

Another scenario is IAsyncOperation<Anything[]>. It seems like MIDL 3.0 simply doesn't support nested generic types or arrays on any level. If you use IAsyncOperation with a basic type it's fine.

I looked everywhere for an example MIDL returning an IAsyncOperation collection but came up empty. Any insights? or do we have to reinvent the wheel defining a custom collection wrapper every time we need to return an array asynchronously? Seems a bit much..


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

stevewhims commented 5 years ago

The first issue turns out to be a whitespace issue. I can repro the issue but then if I add whitespace like this, it's fine:

Windows.Foundation.IAsyncOperation< Windows.Foundation.Collections.IVector< String > > ListThingsAsync();

This used to be an issue with C++ templates, too (not sure whether it still is). I got into the habit of adding a single space of padding inside all my angle brackets.

And, I've confirmed that it's not valid to use an array in that context (arrays are represented as a single parameter in metadata but as two tied parameters at the application binary interface layer). However, see whether IReferenceArray\<T> can help you there.

I've added this info to the intro and to the troubleshooting topics.

Thanks! ~Steve

sichbo commented 5 years ago

Phew! Nice find! Being able to nest generics will reduce a lot of an API's footprint and boilerplate code. Good note about IReferenceArray. Thanks for all of that, Steve 🍺

stevewhims commented 5 years ago

Always welcome, Simon. Thanks to you for developing with MIDL 3.0 and C++/WinRT! :) ~Steve