PtrToStructure
Note that Mono does not have this restriction:
https://github.com/mono/mono/blob/bd278dd00dd24b3e8c735a4220afa6cb3ba317ee/netcore/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.Mono.cs#L311-L316 (Note specifically line 314).
Related: https://github.com/dotnet/coreclr/pull/23899
/cc @jkoritzinsky
Closing per recommended workflow described at https://github.com/dotnet/coreclr/pull/27840#issuecomment-553105457
With further investigation, this issue is not resolved.
Marshal.PtrToStructure actually converts unmanaged function pointers to GC'd delegates, so vtables aren't blittable and can't use casting as Jan recommends.
Further, using a formatted reference type (class with struct layout) vs a struct is not ideal, since it requires a GC allocation. It doesn't appear possible to fold that allocation into a larger object and only marshal a portion of it.
You could, however, manually marshal the fields.
That is, you can define a struct IUnknownVtbl { IntPtr QueryInterface; IntPtr AddRef; IntPtr Release; }, use that for the interop case, and then call Marshal.GetDelegateForFunctionPointer on each field (and the reverse when needing to marshal).
It should provide the same functionality as what Marshal.PtrToStructure would do.
C# 9 is also (assuming it doesn't get pulled out) currently targeting the addition of function pointers, which would make the manual VTBL scenario both blittable and readily usable (without needing to create delegates).
@tannergooding Yes, that is an approach and will work in many cases however there are still issues in some scenarios involving generics - these are going to have to be handled one off. The function pointers work is the gold star here and hopefully that will come on line sooner rather than later.
Yes, unfortunately GetDelegateForFunctionPointer suffers from the same limitation as PtrToStructure - no support for generics. See also: https://github.com/dotnet/coreclr/issues/1685
@Scottj1s This is looking less likely to happen. Do you feel this is still needed for your work?
@Scottj1s This is looking less likely to happen. Do you feel this is still needed for your work?
No, not any more. I have a reasonable workaround in Expression.GetDelegateType