Closed jkoritzinsky closed 1 month ago
"CCW-based interop would be more difficult and may not be as easy to do"
What would that be like, hypothetically? CCW support is also something that's needed in a lot of scenarios. For instance, if you want to roll your own IBuffer
implementation, or eg. to properly implement custom Win2D effects. I assume this would allow replacing all the handrwitten code (like this) with the new COM generators, but it wouldn't make it AOT friendly per se? I mean, this scenario isn't using [ComImport]
already, no? 🤔
It would be very nice to have this functionality to support interfaces like IDataTransferManagerInterop in a trim-friendly way. I did a quick test and updated the AsInterface() method in ObjectReference.cs to check for the GeneratedComInterfaceAttribute and call StrategyBasedComWrappers.GetOrCreateObjectForComInstance() instead of Marshal.GetObjectForIUnknown(). This seems to work fine but I do not know if this is the right way to implement this functionality.
Well, I'd say regardless of whether that specific implementation is the same, for sure we'll need to remove that Marshal.GetObjectForIUnknown
call, as that's completely not supported on NativeAOT anyway (as is [ComImport]
) 😅
It it possible to generate trim/AOT-safe COMWrapper by hand in .NET8 with these source generators currently? Like @lhak I try to get DataTransferManager
to work but no luck so far.
Is this supposed to work with the latest cswinrt preview release? I tried to access the IMemoryBufferByteAccess interface of a IMemoryBufferReference object, but a simple cast or calling reference.As
Are you sure that the object implements that interface (with the correct IID and everything)? It will throw that exception if QueryInterface returns an invalid cast error code.
@dongle-the-gadget Yes, I currently use code based on a helper class with the [WindowsRuntimeType] attribute and StrategyBasedComWrappers to not rely on the built-in com support. I also tried calling Marshal.QueryInterface() on the ((IWinRTObject)obj).NativeObject.ThisPtr pointer with the IMemoryBufferByteAccess iid and this also works fine.
Don’t use StrategyBasedComWrappers, that won’t work.
Cast the WinRT object to the object keyword then cast that to the interface you want. There should be a unit test in the AOT branch that demonstrates generated COM interface usage.
Scratch that, seems like C#/WinRT did not build the .NET 8 target, which is required for this functionality.
Proposal: Implement interop with .NET source generated
GeneratedComInterface
interfacesSummary
In .NET 8, the .NET team has introduced source-generated COM through the
GeneratedComInterface
attribute and a corresponding source-generator. Currently, CsWinRT supports interop with[ComImport]
interfaces through the.As()
method. This mechanism as it exists today will not work withGeneratedComInterface
attributes.However, CsWinRT could extend the
IWinRTObject
interface to implement the contract interface (IUnmanagedVirtualMethodTableProvider) thatGeneratedComInterface
uses to resolve thethis
pointer and vtable and use theStrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy
to resolve the implementation types from the public interface types. This would allow for seamless interop for WinRT types that also implement COM interfaces defined withGeneratedComInterface
.Rationale
ComImport
-based COM interop is not.Important Notes
This issue only covers RCW-based interop between the two systems. CCW-based interop would be more difficult and may not be as easy to do (and as a result is not included in the scope of this issue).
Open Questions