From 686cead239f87ee0aac0a16330beb8e5f7ad253a Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 13 Aug 2020 16:23:06 -0700 Subject: [PATCH] Add fallback for when an interface is kept alive but its Vftbl type was linked away since no members on the interface were called. --- WinRT.Runtime/IWinRTObject.net5.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/WinRT.Runtime/IWinRTObject.net5.cs b/WinRT.Runtime/IWinRTObject.net5.cs index fbd7df330..458679a3e 100644 --- a/WinRT.Runtime/IWinRTObject.net5.cs +++ b/WinRT.Runtime/IWinRTObject.net5.cs @@ -15,7 +15,6 @@ bool IDynamicInterfaceCastable.IsInterfaceImplemented(RuntimeTypeHandle interfac { return false; } - var vftblType = helperType.GetNestedType("Vftbl"); int hr = NativeObject.TryAs(GuidGenerator.GetIID(helperType), out var objRef); if (hr < 0) { @@ -25,6 +24,20 @@ bool IDynamicInterfaceCastable.IsInterfaceImplemented(RuntimeTypeHandle interfac } return false; } + var vftblType = helperType.GetNestedType("Vftbl"); + if (vftblType is null) + { + // The helper type might not have a vftbl type if it was linked away. + // The only time the Vftbl type would be linked away is when we don't actually use + // any of the methods on the interface (it was just a type cast/"is Type" check). + // In that case, we can use the IUnknownVftbl-typed ObjectReference since + // it has all of the information we'll need. + if (!QueryInterfaceCache.TryAdd(interfaceType, objRef)) + { + objRef.Dispose(); + } + return true; + } using (objRef) { IObjectReference typedObjRef = (IObjectReference)typeof(IObjectReference).GetMethod("As", Type.EmptyTypes).MakeGenericMethod(vftblType).Invoke(objRef, null);