Skip to content

Commit

Permalink
Remove more warnings, and a leftover method
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed Jan 25, 2024
1 parent f78c8af commit 9056fba
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 32 deletions.
50 changes: 28 additions & 22 deletions src/WinRT.Runtime/ComWrappersSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -385,31 +385,37 @@ private static Func<IInspectable, object> CreateKeyValuePairFactory(Type type)
return createRcwFunc;
}

internal static Func<IntPtr, object> CreateDelegateFactory(Type type)
internal static Func<IntPtr, object> GetOrCreateDelegateFactory(Type type)
{
return DelegateFactoryCache.GetOrAdd(type, (type) =>
{
var createRcwFunc = (Func<IntPtr, object>)type.GetHelperType().GetMethod("CreateRcw", BindingFlags.Public | BindingFlags.Static).
CreateDelegate(typeof(Func<IntPtr, object>));
var iid = GuidGenerator.GetIID(type);
return DelegateFactoryCache.GetOrAdd(type, CreateDelegateFactory);
}

#if NET
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2067",
Justification = "The type is a delegate type, so 'GuidGenerator.GetIID' doesn't need to access public fields from it (it uses the helper type).")]
#endif
private static Func<IntPtr, object> CreateDelegateFactory(Type type)
{
var createRcwFunc = (Func<IntPtr, object>)type.GetHelperType().GetMethod("CreateRcw", BindingFlags.Public | BindingFlags.Static).
CreateDelegate(typeof(Func<IntPtr, object>));
var iid = GuidGenerator.GetIID(type);

return (IntPtr externalComObject) =>
return (IntPtr externalComObject) =>
{
// The CreateRCW function for delegates expect the pointer to be the delegate interface in CsWinRT 1.5.
// But CreateObject is passed the IUnknown interface. This would typically be fine for delegates as delegates
// don't implement interfaces and implementations typically have both the IUnknown vtable and the delegate
// vtable point to the same vtable. But when the pointer is to a proxy, that can not be relied on.
Marshal.ThrowExceptionForHR(Marshal.QueryInterface(externalComObject, ref iid, out var ptr));
try
{
// The CreateRCW function for delegates expect the pointer to be the delegate interface in CsWinRT 1.5.
// But CreateObject is passed the IUnknown interface. This would typically be fine for delegates as delegates
// don't implement interfaces and implementations typically have both the IUnknown vtable and the delegate
// vtable point to the same vtable. But when the pointer is to a proxy, that can not be relied on.
Marshal.ThrowExceptionForHR(Marshal.QueryInterface(externalComObject, ref iid, out var ptr));
try
{
return createRcwFunc(ptr);
}
finally
{
Marshal.Release(ptr);
}
};
});
return createRcwFunc(ptr);
}
finally
{
Marshal.Release(ptr);
}
};
}

public static bool RegisterDelegateFactory(Type implementationType, Func<IntPtr, object> delegateFactory) => DelegateFactoryCache.TryAdd(implementationType, delegateFactory);
Expand Down
5 changes: 1 addition & 4 deletions src/WinRT.Runtime/ComWrappersSupport.net5.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,6 @@ internal static IntPtr CreateCCWForObjectForABI(object obj, Guid iid)
public static unsafe T FindObject<T>(IntPtr ptr)
where T : class => ComInterfaceDispatch.GetInstance<T>((ComInterfaceDispatch*)ptr);

private static T FindDelegate<T>(IntPtr thisPtr)
where T : class, System.Delegate => FindObject<T>(thisPtr);

public static IUnknownVftbl IUnknownVftbl => DefaultComWrappers.IUnknownVftbl;
public static IntPtr IUnknownVftblPtr => DefaultComWrappers.IUnknownVftblPtr;

Expand Down Expand Up @@ -551,7 +548,7 @@ private static object CreateObject(IntPtr externalComObject)
{
if (ComWrappersSupport.CreateRCWType != null && ComWrappersSupport.CreateRCWType.IsDelegate())
{
return ComWrappersSupport.CreateDelegateFactory(ComWrappersSupport.CreateRCWType)(externalComObject);
return ComWrappersSupport.GetOrCreateDelegateFactory(ComWrappersSupport.CreateRCWType)(externalComObject);
}
else if (Marshal.QueryInterface(externalComObject, ref inspectableIID, out ptr) == 0)
{
Expand Down
2 changes: 1 addition & 1 deletion src/WinRT.Runtime/ComWrappersSupport.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ private static T CreateRcwForComObject<T>(IntPtr ptr, bool tryUseCache)
object runtimeWrapper = null;
if (typeof(T).IsDelegate())
{
runtimeWrapper = CreateDelegateFactory(typeof(T))(ptr);
runtimeWrapper = GetOrCreateDelegateFactory(typeof(T))(ptr);
}
else if (identity.TryAs<IInspectable.Vftbl>(out var inspectableRef) == 0)
{
Expand Down
9 changes: 4 additions & 5 deletions src/WinRT.Runtime/Marshalers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1700,14 +1700,13 @@ public static T FromAbi<T>(IntPtr nativeDelegate)
{
return null;
}
else if (IUnknownVftbl.IsReferenceToManagedObject(nativeDelegate))

if (IUnknownVftbl.IsReferenceToManagedObject(nativeDelegate))
{
return ComWrappersSupport.FindObject<T>(nativeDelegate);
}
else
{
return ComWrappersSupport.CreateRcwForComObject<T>(nativeDelegate);
}

return ComWrappersSupport.CreateRcwForComObject<T>(nativeDelegate);
}
}

Expand Down

0 comments on commit 9056fba

Please sign in to comment.