contextfree / winrt-rust

Use and (eventually) make Windows Runtime APIs with Rust
Apache License 2.0
142 stars 10 forks source link

Generate correct IIDs for parametrized interfaces #4

Closed Boddlnagg closed 7 years ago

Boddlnagg commented 8 years ago

For parametric interface types such as AsyncOperationCompletedHandler<TResult>, the SDK header files include definitions of all used specializations of the generic parameter, together with IIDs. These IIDs are deterministic and I was wondering where they are coming from, so I found this blog post, especially the section on "Generic Interfaces" is helpful. The key is the function RoGetParameterizedTypeInstanceIID.

I will probably add that metadata API to my winapi PR, but since the idea was to generate the bindings with some F# or C# program, it's not that important. Some comments also indicate that the API might only be usable from within a Windows Store App, so of course the best thing would be to know the algorithm used to generate those IIDs (see also the last paragraph of the blog post: The somewhat problematic thing about this is this might be difficult to include in a compiler, because the APIs are only available on Win8, so there's no way to generate the GUIDs from a older version of Windows. It'd be nice if Microsoft provided information on how those GUIDs are constructed so other tools that run on other Windows platforms can cross-build for Win8.)

Boddlnagg commented 8 years ago

Might also be helpful: https://github.com/dotnet/coreclr/blob/8c85c81/src/vm/interoputil.cpp#L5991 and https://github.com/dotnet/coreclr/blob/024178d/src/inc/winrt/paraminstanceapi.h#L1136. This seems to be the full implementation of RoGetParameterizedTypeInstanceIID as part of the MIT-licensed CoreCLR.

Boddlnagg commented 8 years ago

I managed to generate some correct IIDs myself: The algorithm is based on the deterministic GUID generation according to RFC 4122 with SHA-1, using 11F47AD5-7B73-42C0-ABAE-878B1E16ADEE as the base GUID, and a string that encodes the type.

For example:

I think we can implement this algorithm in the code that will be generating our interfaces.

Boddlnagg commented 8 years ago

This is mostly implemented in my branch now.