Skip to content

Commit

Permalink
Make QueryInterface function pointer blittable (#1240)
Browse files Browse the repository at this point in the history
* Try removing ref and out from QueryInterface

* Simplify
  • Loading branch information
manodasanW authored Aug 13, 2022
1 parent 05f36a5 commit e75a025
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 16 deletions.
4 changes: 3 additions & 1 deletion src/WinRT.Runtime/ApiCompatBaseline.net5.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ MembersMustExist : Member 'public void WinRT.MarshalString..ctor()' does not exi
TypesMustExist : Type 'WinRT.MarshalString.HStringHeader' does not exist in the implementation but it does exist in the contract.
CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.CompilerGeneratedAttribute' exists on 'WinRT.SingleInterfaceOptimizedObject.WinRT.IWinRTObject.get_AdditionalTypeData()' in the contract but not the implementation.
CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.CompilerGeneratedAttribute' exists on 'WinRT.SingleInterfaceOptimizedObject.WinRT.IWinRTObject.get_QueryInterfaceCache()' in the contract but not the implementation.
Total Issues: 9
MembersMustExist : Member 'public function System.Int32 (System.IntPtr, System.Guid, System.IntPtr) WinRT.Interop.IUnknownVftbl.QueryInterface.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public void WinRT.Interop.IUnknownVftbl.QueryInterface.set(function System.Int32 (System.IntPtr, System.Guid, System.IntPtr))' does not exist in the implementation but it does exist in the contract.
Total Issues: 11
2 changes: 1 addition & 1 deletion src/WinRT.Runtime/ComWrappersSupport.net5.cs
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ static unsafe DefaultComWrappers()
IUnknownVftblPtr = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IUnknownVftbl), sizeof(IUnknownVftbl));
(*(IUnknownVftbl*)IUnknownVftblPtr) = new IUnknownVftbl
{
QueryInterface = (delegate* unmanaged[Stdcall]<IntPtr, ref Guid, out IntPtr, int>)qi,
QueryInterface = (delegate* unmanaged[Stdcall]<IntPtr, Guid*, IntPtr*, int>)qi,
AddRef = (delegate* unmanaged[Stdcall]<IntPtr, uint>)addRef,
Release = (delegate* unmanaged[Stdcall]<IntPtr, uint>)release,
};
Expand Down
10 changes: 5 additions & 5 deletions src/WinRT.Runtime/ComWrappersSupport.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,19 @@ static unsafe ComWrappersSupport()
IUnknownVftblPtr = Marshal.AllocHGlobal(sizeof(IUnknownVftbl));
(*(IUnknownVftbl*)IUnknownVftblPtr) = new IUnknownVftbl
{
QueryInterface = (delegate* unmanaged[Stdcall]<IntPtr, ref Guid, out IntPtr, int>)Marshal.GetFunctionPointerForDelegate(Abi_QueryInterface),
QueryInterface = (delegate* unmanaged[Stdcall]<IntPtr, Guid*, IntPtr*, int>)Marshal.GetFunctionPointerForDelegate(Abi_QueryInterface),
AddRef = (delegate* unmanaged[Stdcall]<IntPtr, uint>)Marshal.GetFunctionPointerForDelegate(Abi_AddRef),
Release = (delegate* unmanaged[Stdcall]<IntPtr, uint>)Marshal.GetFunctionPointerForDelegate(Abi_Release),
};
}

public static IntPtr AllocateVtableMemory(Type vtableType, int size) => Marshal.AllocCoTaskMem(size);

private delegate int QueryInterface(IntPtr pThis, ref Guid iid, out IntPtr ptr);
private static QueryInterface Abi_QueryInterface = Do_Abi_QueryInterface;
private static int Do_Abi_QueryInterface(IntPtr pThis, ref Guid iid, out IntPtr ptr)
private unsafe delegate int QueryInterface(IntPtr pThis, Guid* iid, IntPtr* ptr);
private unsafe static QueryInterface Abi_QueryInterface = Do_Abi_QueryInterface;
private unsafe static int Do_Abi_QueryInterface(IntPtr pThis, Guid* iid, IntPtr* ptr)
{
return UnmanagedObject.FindObject<ComCallableWrapper>(pThis).QueryInterface(iid, out ptr);
return UnmanagedObject.FindObject<ComCallableWrapper>(pThis).QueryInterface(*iid, out *ptr);
}

private delegate uint AddRefRelease(IntPtr pThis);
Expand Down
2 changes: 1 addition & 1 deletion src/WinRT.Runtime/Interop/IUnknownVftbl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace WinRT.Interop
unsafe struct IUnknownVftbl
{
private void* _QueryInterface;
public delegate* unmanaged[Stdcall]<IntPtr, ref Guid, out IntPtr, int> QueryInterface { get => (delegate* unmanaged[Stdcall]<IntPtr, ref Guid, out IntPtr, int>)_QueryInterface; set => _QueryInterface = (void*)value; }
public delegate* unmanaged[Stdcall]<IntPtr, Guid*, IntPtr*, int> QueryInterface { get => (delegate* unmanaged[Stdcall]<IntPtr, Guid*, IntPtr*, int>)_QueryInterface; set => _QueryInterface = (void*)value; }
private void* _AddRef;
public delegate* unmanaged[Stdcall]<IntPtr, uint> AddRef { get => (delegate* unmanaged[Stdcall]<IntPtr, uint>)_AddRef; set => _AddRef = (void*)value; }
private void* _Release;
Expand Down
8 changes: 5 additions & 3 deletions src/WinRT.Runtime/MatchingRefApiCompatBaseline.net5.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ MembersMustExist : Member 'public WinRT.ObjectReferenceValue ABI.System.Componen
MembersMustExist : Member 'public System.ComponentModel.PropertyChangedEventHandler ABI.System.ComponentModel.PropertyChangedEventHandler.CreateRcw(System.IntPtr)' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'ABI.WinRT.Interop.IWeakReferenceSourceMethods' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Numerics.VectorExtensions' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArrayAttribute' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArrayAttribute' does not exist in the reference but it does exist in the implementation.
CannotRemoveAttribute : Attribute 'WinRT.WindowsRuntimeHelperTypeAttribute' exists on 'Windows.Foundation.Point' in the implementation but not the reference.
CannotRemoveAttribute : Attribute 'WinRT.WindowsRuntimeHelperTypeAttribute' exists on 'Windows.Foundation.Rect' in the implementation but not the reference.
CannotRemoveAttribute : Attribute 'WinRT.WindowsRuntimeHelperTypeAttribute' exists on 'Windows.Foundation.Size' in the implementation but not the reference.
Expand Down Expand Up @@ -59,8 +61,8 @@ TypesMustExist : Type 'WinRT.ObjectReferenceValue' does not exist in the referen
TypesMustExist : Type 'WinRT.WindowsRuntimeHelperTypeAttribute' does not exist in the reference but it does exist in the implementation.
CannotRemoveAttribute : Attribute 'WinRT.WindowsRuntimeHelperTypeAttribute' exists on 'WinRT.Interop.IActivationFactory' in the implementation but not the reference.
CannotRemoveAttribute : Attribute 'WinRT.WindowsRuntimeHelperTypeAttribute' exists on 'WinRT.Interop.IAgileObject' in the implementation but not the reference.
MembersMustExist : Member 'public function System.Int32 (System.IntPtr, System.Guid*, System.IntPtr*) WinRT.Interop.IUnknownVftbl.QueryInterface.get()' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public void WinRT.Interop.IUnknownVftbl.QueryInterface.set(function System.Int32 (System.IntPtr, System.Guid*, System.IntPtr*))' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'WinRT.Interop.IWeakReference' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'WinRT.Interop.IWeakReferenceSource' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArrayAttribute' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArrayAttribute' does not exist in the reference but it does exist in the implementation.
Total Issues: 64
Total Issues: 66
15 changes: 10 additions & 5 deletions src/WinRT.Runtime/ObjectReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ public unsafe TInterface AsInterface<TInterface>()
if (typeof(TInterface).IsDefined(typeof(System.Runtime.InteropServices.ComImportAttribute)))
{
Guid iid = typeof(TInterface).GUID;
Marshal.ThrowExceptionForHR(VftblIUnknown.QueryInterface(ThisPtr, ref iid, out IntPtr comPtr));
IntPtr comPtr = IntPtr.Zero;
Marshal.ThrowExceptionForHR(VftblIUnknown.QueryInterface(ThisPtr, &iid, &comPtr));
try
{
return (TInterface)Marshal.GetObjectForIUnknown(comPtr);
Expand Down Expand Up @@ -178,7 +179,8 @@ public virtual unsafe int TryAs<
{
objRef = null;
ThrowIfDisposed();
int hr = VftblIUnknown.QueryInterface(ThisPtr, ref iid, out IntPtr thatPtr);
IntPtr thatPtr = IntPtr.Zero;
int hr = VftblIUnknown.QueryInterface(ThisPtr, &iid, &thatPtr);
if (hr >= 0)
{
if (IsAggregated)
Expand Down Expand Up @@ -214,7 +216,8 @@ public virtual unsafe int TryAs(Guid iid, out IntPtr ppv)
{
ppv = IntPtr.Zero;
ThrowIfDisposed();
int hr = VftblIUnknown.QueryInterface(ThisPtr, ref iid, out IntPtr thatPtr);
IntPtr thatPtr = IntPtr.Zero;
int hr = VftblIUnknown.QueryInterface(ThisPtr, &iid, &thatPtr);
if (hr >= 0)
{
ppv = thatPtr;
Expand Down Expand Up @@ -387,7 +390,8 @@ public ObjectReferenceValue AsValue()

public unsafe ObjectReferenceValue AsValue(Guid iid)
{
Marshal.ThrowExceptionForHR(VftblIUnknown.QueryInterface(ThisPtr, ref iid, out IntPtr thatPtr));
IntPtr thatPtr = IntPtr.Zero;
Marshal.ThrowExceptionForHR(VftblIUnknown.QueryInterface(ThisPtr, &iid, &thatPtr));
if (IsAggregated)
{
Marshal.Release(thatPtr);
Expand Down Expand Up @@ -641,7 +645,8 @@ public override unsafe int TryAs<
{
objRef = null;

int hr = VftblIUnknown.QueryInterface(ThisPtr, ref iid, out IntPtr thatPtr);
IntPtr thatPtr = IntPtr.Zero;
int hr = VftblIUnknown.QueryInterface(ThisPtr, &iid, &thatPtr);
if (hr >= 0)
{
if (IsAggregated)
Expand Down

0 comments on commit e75a025

Please sign in to comment.