microsoft / CsWin32

A source generator to add a user-defined set of Win32 P/Invoke methods and supporting types to a C# project.
MIT License
2.1k stars 90 forks source link

Better Marshalling of WinRT Types in Win32 Methods #887

Open smj389 opened 1 year ago

smj389 commented 1 year ago

At the moment, methods with WinRT types are generated like this:

[DllImport("CoreMessaging.dll", ExactSpelling = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
internal static extern winmdroot.Foundation.HRESULT CreateDispatcherQueueController(
   winmdroot.System.WinRT.DispatcherQueueOptions options,
   [MarshalAs(UnmanagedType.CustomMarshaler,MarshalCookie = "Windows.System.DispatcherQueueController",MarshalType = "Windows.Win32.CsWin32.InteropServices.WinRTCustomMarshaler")] out global::Windows.System.DispatcherQueueController dispatcherQueueController);

Where WinRTCustomMarashaler is a piece of generated code that uses reflection and MethodInfo.invoke.

Surely, it would be more efficient to do something like this:

[DllImport("CoreMessaging.dll", ExactSpelling = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private static extern Windows.Win32.Foundation.HRESULT CreateDispatcherQueueController(
   DispatcherQueueOptions options,
   out nint dispatcherQueueController);

public static Windows.Win32.Foundation.HRESULT CreateDispatcherQueueController(
   DispatcherQueueOptions options,
   out DispatcherQueueController? dispatcherQueueController)
{
   var result = CreateDispatcherQueueController(options, out nint dispatcherQueueControllerNative);
   dispatcherQueueController = result.Succeeded
      ? DispatcherQueueController.FromAbi(dispatcherQueueControllerNative)
      : null;
   return result;
}

The main difference is that for each type there is a FromAbi static method that can be called. Given that the type is known at code generation time surely that is more efficient.

smj389 commented 1 year ago

Please excuse the formatting.

AArnott commented 1 year ago

@smj389 use triple backticks for better formatting. Add cs after them for colorization.

AArnott commented 1 year ago

@smj389 Thank you for the suggestion. It looks good, although I'm not too familiar with WinRT interop.

@sotteson1 I believe you contributed the WinRTCustomMarshaler type. Do you have any insights into this suggestion?