Skip to content

Commit

Permalink
Add vtbls for IWeakReferenceSOurce and IWeakReference.
Browse files Browse the repository at this point in the history
  • Loading branch information
jlaanstra committed Mar 14, 2023
1 parent ea463c3 commit 4182294
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/WinRT.Runtime/ComWrappersSupport.net5.cs
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ private static object CreateObject(IntPtr externalComObject)
{
// IWeakReference is IUnknown-based, so implementations of it may not (and likely won't) implement
// IInspectable. As a result, we need to check for them explicitly.
var iunknownObjRef = ComWrappersSupport.GetObjectReferenceForInterface<IUnknownVftbl>(ptr);
var iunknownObjRef = ComWrappersSupport.GetObjectReferenceForInterface<ABI.WinRT.Interop.IWeakReference.Vftbl>(ptr);
ComWrappersHelper.Init(iunknownObjRef);

return new SingleInterfaceOptimizedObject(typeof(IWeakReference), iunknownObjRef, false);
Expand Down
83 changes: 82 additions & 1 deletion src/WinRT.Runtime/Interop/IWeakReferenceSource.net5.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,45 @@ static class IWeakReferenceSourceMethods
[Guid("00000038-0000-0000-C000-000000000046")]
internal unsafe interface IWeakReferenceSource : global::WinRT.Interop.IWeakReferenceSource
{
[Guid("00000038-0000-0000-C000-000000000046")]
internal struct Vftbl
{
public global::WinRT.Interop.IUnknownVftbl IUnknownVftbl;
private void* _GetWeakReference;
public delegate* unmanaged[Stdcall]<IntPtr, out IntPtr, int> GetWeakReference { get => (delegate* unmanaged[Stdcall]<IntPtr, out IntPtr, int>)_GetWeakReference; set => _GetWeakReference = value; }

public static readonly Vftbl AbiToProjectionVftable;
public static readonly IntPtr AbiToProjectionVftablePtr;

internal delegate int GetWeakReferenceDelegate(IntPtr thisPtr, IntPtr* weakReference);
private static readonly Delegate[] DelegateCache = new Delegate[1];
static Vftbl()
{
AbiToProjectionVftable = new Vftbl
{
IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl,
_GetWeakReference = Marshal.GetFunctionPointerForDelegate(DelegateCache[0] = new GetWeakReferenceDelegate(Do_Abi_GetWeakReference)).ToPointer(),
};
AbiToProjectionVftablePtr = Marshal.AllocHGlobal(Marshal.SizeOf<Vftbl>());
Marshal.StructureToPtr(AbiToProjectionVftable, AbiToProjectionVftablePtr, false);
}

private static int Do_Abi_GetWeakReference(IntPtr thisPtr, IntPtr* weakReference)
{
*weakReference = default;

try
{
*weakReference = ComWrappersSupport.CreateCCWForObject(new global::WinRT.Interop.ManagedWeakReference(ComWrappersSupport.FindObject<object>(thisPtr))).As<ABI.WinRT.Interop.IWeakReference.Vftbl>().GetRef();
}
catch (Exception __exception__)
{
return __exception__.HResult;
}
return 0;
}
}

internal static readonly Guid IID = InterfaceIIDs.IWeakReferenceSource_IID;

public static IntPtr AbiToProjectionVftablePtr;
Expand Down Expand Up @@ -131,6 +170,48 @@ private static int Do_Abi_GetWeakReference(IntPtr thisPtr, IntPtr* weakReference
[Guid("00000037-0000-0000-C000-000000000046")]
internal unsafe interface IWeakReference : global::WinRT.Interop.IWeakReference
{
[Guid("00000037-0000-0000-C000-000000000046")]
public struct Vftbl
{
public global::WinRT.Interop.IUnknownVftbl IUnknownVftbl;
private void* _Resolve;
public delegate* unmanaged[Stdcall]<IntPtr, ref Guid, out IntPtr, int> Resolve { get => (delegate* unmanaged[Stdcall]<IntPtr, ref Guid, out IntPtr, int>)_Resolve; set => _Resolve = value; }

public static readonly Vftbl AbiToProjectionVftable;
public static readonly IntPtr AbiToProjectionVftablePtr;

public delegate int ResolveDelegate(IntPtr thisPtr, Guid* riid, IntPtr* objectReference);
private static readonly Delegate[] DelegateCache = new Delegate[1];
static Vftbl()
{
AbiToProjectionVftable = new Vftbl
{
IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl,
_Resolve = Marshal.GetFunctionPointerForDelegate(DelegateCache[0] = new ResolveDelegate(Do_Abi_Resolve)).ToPointer(),
};
AbiToProjectionVftablePtr = Marshal.AllocHGlobal(Marshal.SizeOf<Vftbl>());
Marshal.StructureToPtr(AbiToProjectionVftable, AbiToProjectionVftablePtr, false);
}

private static int Do_Abi_Resolve(IntPtr thisPtr, Guid* riid, IntPtr* objectReference)
{
IObjectReference _objectReference = default;

*objectReference = default;

try
{
_objectReference = global::WinRT.ComWrappersSupport.FindObject<global::WinRT.Interop.IWeakReference>(thisPtr).Resolve(*riid);
*objectReference = _objectReference?.GetRef() ?? IntPtr.Zero;
}
catch (Exception __exception__)
{
return __exception__.HResult;
}
return 0;
}
}

internal static readonly Guid IID = new(0x00000037, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);

public static IntPtr AbiToProjectionVftablePtr;
Expand Down Expand Up @@ -181,6 +262,6 @@ private static int Do_Abi_Resolve(IntPtr thisPtr, Guid* riid, IntPtr* objectRefe
{
MarshalInspectable<object>.DisposeAbi(objRef);
}
}
}
}
}
7 changes: 4 additions & 3 deletions src/cswinrt/strings/WinRT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -540,12 +540,12 @@ public static void Create(IObjectReference obj, int index, System.WeakReference<
return;
}
#else
int hr = obj.TryAs<IUnknownVftbl>(InterfaceIIDs.IWeakReferenceSource_IID, out var weakRefSource);
int hr = obj.TryAs<ABI.WinRT.Interop.IWeakReferenceSource.Vftbl>(InterfaceIIDs.IWeakReferenceSource_IID, out var weakRefSource);
if (hr != 0)
{
return;
}

}

target = ABI.WinRT.Interop.IWeakReferenceSourceMethods.GetWeakReference(weakRefSource);
#endif

Expand Down Expand Up @@ -860,6 +860,7 @@ internal static class InterfaceIIDs
internal static readonly Guid IInspectable_IID = new(0xAF86E2E0, 0xB12D, 0x4c6a, 0x9C, 0x5A, 0xD7, 0xAA, 0x65, 0x10, 0x1E, 0x90);
internal static readonly Guid IUnknown_IID = new(0, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
internal static readonly Guid IWeakReferenceSource_IID = new(0x00000038, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
internal static readonly Guid IWeakReference_IID = new(0x00000037, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
}
}

Expand Down

0 comments on commit 4182294

Please sign in to comment.