Open
Description
Contributes to #114024
Same motivation and context as the linked issue. This proposal is for an ILC-friendly set of APIs to build IUnknown
CCW vtables.
Original suggestion for the shape by @jkotas in #114024 (comment).
Important
We can't just use the existing ComWrappers.GetIUnknownImpl
, as its shape is too difficult for ILC to interpret it.
API Proposal
namespace System.Runtime.InteropServices;
public abstract class ComWrappers
{
public static IntPtr GetIUnknownQueryInterfaceImpl();
public static IntPtr GetIUnknownAddRefImpl();
public static IntPtr GetIUnknownReleaseImpl();
}
API Usage
// Eg. in WinRT.Runtime.dll
internal unsafe struct IInspectableVftbl
{
public delegate* unmanaged[MemberFunction]<void*, Guid*, void**, int> QueryInterface;
public delegate* unmanaged[MemberFunction]<void*, uint> AddRef;
public delegate* unmanaged[MemberFunction]<void*, uint> Release;
public delegate* unmanaged[MemberFunction]<void*, uint*, Guid**, int> GetIids;
public delegate* unmanaged[MemberFunction]<void*, nint*, int> GetRuntimeClassName;
public delegate* unmanaged[MemberFunction]<void*, int*, int> GetTrustLevel;
}
internal static unsafe class IInspectableImpl
{
[FixedAddressValueType]
private static readonly IInspectableVftbl Vftbl;
public static nint AbiToProjectionVftablePtr => (nint)Unsafe.AsPointer(ref Unsafe.AsRef(in Vftbl));
static IInspectableImpl()
{
Vftbl.QueryInterface = (delegate* unmanaged[MemberFunction]<void*, Guid*, void**, int>)ComWrappers.GetIUnknownQueryInterfaceImpl();
Vftbl.AddRef = (delegate* unmanaged[MemberFunction]<void*, uint>)ComWrappers.GetIUnknownAddRefImpl();
Vftbl.Release = (delegate* unmanaged[MemberFunction]<void*, uint>)ComWrappers.GetIUnknownReleaseImpl();
Vftbl.GetIids = &GetIids;
Vftbl.GetRuntimeClassName = &GetRuntimeClassName;
Vftbl.GetTrustLevel = &GetTrustLevel;
}
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
private static int GetIids(void* thisPtr, uint* iidCount, Guid** iids)
{
*iidCount = 0;
*iids = null;
return 0;
}
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
private static int GetRuntimeClassName(void* thisPtr, nint* className)
{
*className = default;
return 0;
}
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
private static int GetTrustLevel(void* thisPtr, int* trustLevel)
{
*trustLevel = 0;
return 0;
}
}
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
No status