From cc51785fdbf5dcd16d8c4a1891752852452a3c28 Mon Sep 17 00:00:00 2001 From: Manodasan Wignarajah Date: Sat, 26 Feb 2022 21:20:44 -0800 Subject: [PATCH] Make MarshalGeneric use ObjectReferenceValue. --- src/WinRT.Runtime/AgileReference.cs | 36 +++-- src/WinRT.Runtime/CastExtensions.cs | 4 + .../Interop/IAgileReference.net5.cs | 6 +- .../Interop/IAgileReference.netstandard2.0.cs | 6 +- src/WinRT.Runtime/Marshalers.cs | 150 ++++++++++++------ .../MatchingRefApiCompatBaseline.net5.0.txt | 4 +- src/WinRT.Runtime/Projections/KeyValuePair.cs | 5 +- src/WinRT.Runtime/TypeExtensions.cs | 5 +- src/cswinrt/code_writers.h | 20 +-- 9 files changed, 152 insertions(+), 84 deletions(-) diff --git a/src/WinRT.Runtime/AgileReference.cs b/src/WinRT.Runtime/AgileReference.cs index efffe18a8..3d86cb2ae 100644 --- a/src/WinRT.Runtime/AgileReference.cs +++ b/src/WinRT.Runtime/AgileReference.cs @@ -18,15 +18,25 @@ class AgileReference : IDisposable private readonly static Lazy Git = new Lazy(() => GetGitTable()); private readonly IObjectReference _agileReference; private readonly IntPtr _cookie; - private bool disposed; - - public unsafe AgileReference(IObjectReference instance) + private bool disposed; + + public AgileReference(IObjectReference instance) + : this(instance?.ThisPtr ?? IntPtr.Zero) + { + } + + internal AgileReference(in ObjectReferenceValue instance) + : this(instance.GetAbi()) + { + } + + internal unsafe AgileReference(IntPtr thisPtr) { - if(instance?.ThisPtr == null) + if (thisPtr == IntPtr.Zero) { return; - } - + } + IntPtr agileReference = default; Guid iid = IUnknownVftbl.IID; try @@ -34,13 +44,13 @@ public unsafe AgileReference(IObjectReference instance) Marshal.ThrowExceptionForHR(Platform.RoGetAgileReference( 0 /*AGILEREFERENCE_DEFAULT*/, ref iid, - instance.ThisPtr, + thisPtr, &agileReference)); _agileReference = ObjectReference.Attach(ref agileReference); } - catch(TypeLoadException) + catch (TypeLoadException) { - _cookie = Git.Value.RegisterInterfaceInGlobal(instance, iid); + _cookie = Git.Value.RegisterInterfaceInGlobal(thisPtr, iid); } finally { @@ -48,6 +58,7 @@ public unsafe AgileReference(IObjectReference instance) } } + public IObjectReference Get() => _cookie == IntPtr.Zero ? ABI.WinRT.Interop.IAgileReferenceMethods.Resolve(_agileReference, IUnknownVftbl.IID) : Git.Value?.GetInterfaceFromGlobal(_cookie, IUnknownVftbl.IID); internal ObjectReference Get(Guid iid) => _cookie == IntPtr.Zero ? ABI.WinRT.Interop.IAgileReferenceMethods.Resolve(_agileReference, iid) : Git.Value?.GetInterfaceFromGlobal(_cookie, IUnknownVftbl.IID)?.As(iid); @@ -113,7 +124,12 @@ public void Dispose() sealed class AgileReference : AgileReference where T : class { - public unsafe AgileReference(IObjectReference instance) + public AgileReference(IObjectReference instance) + : base(instance) + { + } + + internal AgileReference(in ObjectReferenceValue instance) : base(instance) { } diff --git a/src/WinRT.Runtime/CastExtensions.cs b/src/WinRT.Runtime/CastExtensions.cs index 36141693d..534fef244 100644 --- a/src/WinRT.Runtime/CastExtensions.cs +++ b/src/WinRT.Runtime/CastExtensions.cs @@ -75,6 +75,10 @@ public static AgileReference AsAgile(this T value) where T : class { return new AgileReference(objref); } + else if (marshal is ObjectReferenceValue objrefValue) + { + return new AgileReference(objrefValue); + } } finally { diff --git a/src/WinRT.Runtime/Interop/IAgileReference.net5.cs b/src/WinRT.Runtime/Interop/IAgileReference.net5.cs index 2ebcdb9ea..b0bc9b85e 100644 --- a/src/WinRT.Runtime/Interop/IAgileReference.net5.cs +++ b/src/WinRT.Runtime/Interop/IAgileReference.net5.cs @@ -29,7 +29,7 @@ interface IAgileObject [Guid("00000146-0000-0000-C000-000000000046")] internal interface IGlobalInterfaceTable { - IntPtr RegisterInterfaceInGlobal(IObjectReference objRef, Guid riid); + IntPtr RegisterInterfaceInGlobal(IntPtr ptr, Guid riid); void RevokeInterfaceFromGlobal(IntPtr cookie); IObjectReference GetInterfaceFromGlobal(IntPtr cookie, Guid riid); } @@ -161,9 +161,9 @@ public IGlobalInterfaceTable(ObjectReference obj) _obj = obj; } - public IntPtr RegisterInterfaceInGlobal(IObjectReference objRef, Guid riid) + public IntPtr RegisterInterfaceInGlobal(IntPtr ptr, Guid riid) { - ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.RegisterInterfaceInGlobal(ThisPtr, objRef.ThisPtr, ref riid, out IntPtr cookie)); + ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.RegisterInterfaceInGlobal(ThisPtr, ptr, ref riid, out IntPtr cookie)); return cookie; } diff --git a/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs b/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs index 1052770e2..65f984eda 100644 --- a/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs +++ b/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs @@ -28,7 +28,7 @@ interface IAgileObject [Guid("00000146-0000-0000-C000-000000000046")] internal interface IGlobalInterfaceTable { - IntPtr RegisterInterfaceInGlobal(IObjectReference objRef, Guid riid); + IntPtr RegisterInterfaceInGlobal(IntPtr ptr, Guid riid); void RevokeInterfaceFromGlobal(IntPtr cookie); IObjectReference GetInterfaceFromGlobal(IntPtr cookie, Guid riid); } @@ -225,9 +225,9 @@ public IGlobalInterfaceTable(ObjectReference obj) _obj = obj; } - public IntPtr RegisterInterfaceInGlobal(IObjectReference objRef, Guid riid) + public IntPtr RegisterInterfaceInGlobal(IntPtr ptr, Guid riid) { - ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.RegisterInterfaceInGlobal(ThisPtr, objRef.ThisPtr, ref riid, out IntPtr cookie)); + ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.RegisterInterfaceInGlobal(ThisPtr, ptr, ref riid, out IntPtr cookie)); return cookie; } diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index bbeaafa11..d6b10cc09 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -441,21 +441,38 @@ class MarshalGeneric protected static readonly Type HelperType = typeof(T).GetHelperType(); protected static readonly Type AbiType = typeof(T).GetAbiType(); protected static readonly Type MarshalerType = typeof(T).GetMarshalerType(); + private static readonly bool MarshalByObjectReferenceValue = MarshalerType == typeof(ObjectReferenceValue); public static readonly Func CreateMarshaler = (T value) => CreateMarshalerLazy.Value(value); private static readonly Lazy> CreateMarshalerLazy = new(BindCreateMarshaler); private static Func BindCreateMarshaler() { - var createMarshaler = HelperType.GetMethod("CreateMarshaler", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); - return (T arg) => createMarshaler.Invoke(null, new object[] { arg }); + if (MarshalByObjectReferenceValue) + { + var createMarshaler = (Func)HelperType.GetMethod("CreateMarshaler2", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static). + CreateDelegate(typeof(Func)); + return (T arg) => createMarshaler(arg); + } + else + { + var createMarshaler = HelperType.GetMethod("CreateMarshaler", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + return (T arg) => createMarshaler.Invoke(null, new object[] { arg }); + } } public static readonly Func GetAbi = (object objRef) => GetAbiLazy.Value(objRef); private static readonly Lazy> GetAbiLazy = new(BindGetAbi); private static Func BindGetAbi() { - var getAbi = HelperType.GetMethod("GetAbi", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); - return (object arg) => getAbi.Invoke(null, new[] { arg }); + if (MarshalByObjectReferenceValue) + { + return Marshaler.GetAbiObjectReferenceValueFunc; + } + else + { + var getAbi = HelperType.GetMethod("GetAbi", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + return (object arg) => getAbi.Invoke(null, new[] { arg }); + } } public static readonly Action CopyAbi = (object box, IntPtr dest) => CopyAbiLazy.Value(box, dest); @@ -496,8 +513,15 @@ private static Action BindCopyManaged() private static readonly Lazy> DisposeMarshalerLazy = new(BindDisposeMarshaler); private static Action BindDisposeMarshaler() { - var disposeMarshaler = HelperType.GetMethod("DisposeMarshaler", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); - return (object arg) => disposeMarshaler.Invoke(null, new [] { arg }); + if (MarshalByObjectReferenceValue) + { + return Marshaler.DisposeObjectReferenceValueFunc; + } + else + { + var disposeMarshaler = HelperType.GetMethod("DisposeMarshaler", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + return (object arg) => disposeMarshaler.Invoke(null, new[] { arg }); + } } internal static readonly Action DisposeAbi = (object box) => DisposeAbiLazy.Value(box); @@ -565,8 +589,16 @@ private static Action BindDisposeAbiArray() private static unsafe void CopyManagedFallback(T value, IntPtr dest) { - *(IntPtr*)dest.ToPointer() = - (value is null) ? IntPtr.Zero : ((IObjectReference) CreateMarshaler(value)).GetRef(); + if (MarshalByObjectReferenceValue) + { + *(IntPtr*)dest.ToPointer() = + (value is null) ? IntPtr.Zero : ((ObjectReferenceValue)CreateMarshaler(value)).Detach(); + } + else + { + *(IntPtr*)dest.ToPointer() = + (value is null) ? IntPtr.Zero : ((IObjectReference)CreateMarshaler(value)).GetRef(); + } } internal static unsafe void CopyManagedArray(T[] array, IntPtr data) => MarshalInterfaceHelper.CopyManagedArray(array, data, CopyManagedLazy.Value ?? CopyManagedFallback); @@ -1013,7 +1045,6 @@ struct MarshalInterface private static readonly Type HelperType = typeof(T).GetHelperType(); private static Func _ToAbi; private static Func _CreateMarshaler; - private static Guid _iid = default; public static T FromAbi(IntPtr ptr) { @@ -1073,16 +1104,7 @@ public static ObjectReferenceValue CreateMarshaler2(T value, Guid iid = default) return _ToAbi(value).AsValue(); } - return MarshalInspectable.CreateMarshaler2(value, iid == default ? GetIIDForHelperType() : iid, true); - } - - private static Guid GetIIDForHelperType() - { - if (_iid == default) - { - _iid = GuidGenerator.GetIID(HelperType); - } - return _iid; + return MarshalInspectable.CreateMarshaler2(value, iid == default ? GuidGenerator.GetIID(HelperType) : iid, true); } public static IntPtr GetAbi(IObjectReference value) => @@ -1096,6 +1118,18 @@ public static IntPtr GetAbi(IObjectReference value) => public static void DisposeMarshaler(ObjectReferenceValue value) => MarshalInterfaceHelper.DisposeMarshaler(value); + internal static void DisposeMarshaler(object value) + { + if (value is ObjectReferenceValue objRefValue) + { + DisposeMarshaler(objRefValue); + } + else + { + DisposeMarshaler((IObjectReference)value); + } + } + public static IntPtr FromManaged(T value) { return CreateMarshaler2(value).Detach(); @@ -1106,9 +1140,7 @@ public static unsafe void CopyManaged(T value, IntPtr dest) *(IntPtr*)dest.ToPointer() = CreateMarshaler2(value).Detach(); } - public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(T[] array) => MarshalInterfaceHelper.CreateMarshalerArray(array, (o) => CreateMarshaler(o)); - - public static MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray2(T[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, (o) => CreateMarshaler2(o)); + public static MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(T[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, (o) => CreateMarshaler2(o)); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); @@ -1243,6 +1275,18 @@ public static T FromAbi(IntPtr ptr) public static void DisposeMarshaler(ObjectReferenceValue value) => value.Dispose(); + internal static void DisposeMarshaler(object value) + { + if (value is ObjectReferenceValue objRefValue) + { + DisposeMarshaler(objRefValue); + } + else + { + DisposeMarshaler((IObjectReference)value); + } + } + public static void DisposeAbi(IntPtr ptr) => MarshalInterfaceHelper.DisposeAbi(ptr); public static IntPtr FromManaged(T o, bool unwrapObject = true) { @@ -1254,9 +1298,7 @@ public static unsafe void CopyManaged(T o, IntPtr dest, bool unwrapObject = true *(IntPtr*)dest.ToPointer() = CreateMarshaler2(o, unwrapObject).Detach(); } - public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(T[] array) => MarshalInterfaceHelper.CreateMarshalerArray(array, (o) => CreateMarshaler(o)); - - public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray2(T[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, (o) => CreateMarshaler2(o)); + public static MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(T[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, (o) => CreateMarshaler2(o)); public static (int length, IntPtr data) GetAbiArray(T box) => MarshalInterfaceHelper.GetAbiArray(box); @@ -1335,6 +1377,18 @@ public static T FromAbi(IntPtr nativeDelegate) } } + internal static class Marshaler + { + internal static Action EmptyFunc = (object box) => { }; + internal static Func ReturnParameterFunc = (object box) => box; + internal static unsafe Action CopyIntEnumFunc = + (object value, IntPtr dest) => *(int*)dest.ToPointer() = (int)Convert.ChangeType(value, typeof(int)); + internal static unsafe Action CopyUIntEnumFunc = + (object value, IntPtr dest) => *(uint*)dest.ToPointer() = (uint)Convert.ChangeType(value, typeof(uint)); + internal static Action DisposeObjectReferenceValueFunc = (object arg) => ((ObjectReferenceValue)arg).Dispose(); + internal static Func GetAbiObjectReferenceValueFunc = (object arg) => ((ObjectReferenceValue)arg).GetAbi(); + } + #if EMBED internal #else @@ -1421,29 +1475,27 @@ static Marshaler() if (AbiType == null) { + Func ReturnTypedParameterFunc = (T value) => value; AbiType = type; - CreateMarshaler = (T value) => value; - GetAbi = (object box) => box; + CreateMarshaler = ReturnTypedParameterFunc; + GetAbi = Marshaler.ReturnParameterFunc; FromAbi = (object value) => (T)value; - FromManaged = (T value) => value; - DisposeMarshaler = (object box) => { }; - DisposeAbi = (object box) => { }; + FromManaged = ReturnTypedParameterFunc; + DisposeMarshaler = Marshaler.EmptyFunc; + DisposeAbi = Marshaler.EmptyFunc; if (type.IsEnum) { // For marshaling non-blittable enum arrays via MarshalNonBlittable - unsafe void CopyEnum(object value, IntPtr dest) + if (type.GetEnumUnderlyingType() == typeof(int)) + { + CopyAbi = Marshaler.CopyIntEnumFunc; + CopyManaged = (T value, IntPtr dest) => Marshaler.CopyIntEnumFunc(value, dest); + } + else { - if (type.GetEnumUnderlyingType() == typeof(int)) - { - *(int*)dest.ToPointer() = (int)Convert.ChangeType(value, typeof(int)); - } - else - { - *(uint*)dest.ToPointer() = (uint)Convert.ChangeType(value, typeof(uint)); - } + CopyAbi = Marshaler.CopyUIntEnumFunc; + CopyManaged = (T value, IntPtr dest) => Marshaler.CopyUIntEnumFunc(value, dest); } - CopyAbi = (object value, IntPtr dest) => CopyEnum(value, dest); - CopyManaged = (T value, IntPtr dest) => CopyEnum(value, dest); } CreateMarshalerArray = (T[] array) => MarshalBlittable.CreateMarshalerArray(array); GetAbiArray = (object box) => MarshalBlittable.GetAbiArray(box); @@ -1475,11 +1527,12 @@ unsafe void CopyEnum(object value, IntPtr dest) else if (type.IsInterface) { AbiType = typeof(IntPtr); - CreateMarshaler = (T value) => MarshalInterface.CreateMarshaler(value); - GetAbi = (object objRef) => MarshalInterface.GetAbi((IObjectReference)objRef); + CreateMarshaler = (T value) => MarshalInterface.CreateMarshaler2(value); + GetAbi = (object objRef) => objRef is ObjectReferenceValue objRefValue ? + MarshalInspectable.GetAbi(objRefValue) : MarshalInterface.GetAbi((IObjectReference)objRef); FromAbi = (object value) => MarshalInterface.FromAbi((IntPtr)value); - FromManaged = (T value) => ((IObjectReference)CreateMarshaler(value)).GetRef(); - DisposeMarshaler = (object objRef) => MarshalInterface.DisposeMarshaler((IObjectReference)objRef); + FromManaged = (T value) => MarshalInterface.CreateMarshaler2(value).Detach(); + DisposeMarshaler = MarshalInterface.DisposeMarshaler; DisposeAbi = (object box) => MarshalInterface.DisposeAbi((IntPtr)box); CreateMarshalerArray = (T[] array) => MarshalInterface.CreateMarshalerArray(array); GetAbiArray = (object box) => MarshalInterface.GetAbiArray(box); @@ -1492,12 +1545,13 @@ unsafe void CopyEnum(object value, IntPtr dest) else if (typeof(T) == typeof(object)) { AbiType = typeof(IntPtr); - CreateMarshaler = (T value) => MarshalInspectable.CreateMarshaler(value); - GetAbi = (object objRef) => MarshalInspectable.GetAbi((IObjectReference)objRef); + CreateMarshaler = (T value) => MarshalInspectable.CreateMarshaler2(value); + GetAbi = (object objRef) => objRef is ObjectReferenceValue objRefValue ? + MarshalInspectable.GetAbi(objRefValue) : MarshalInspectable.GetAbi((IObjectReference)objRef); FromAbi = (object box) => MarshalInspectable.FromAbi((IntPtr)box); FromManaged = (T value) => MarshalInspectable.FromManaged(value); CopyManaged = (T value, IntPtr dest) => MarshalInspectable.CopyManaged(value, dest); - DisposeMarshaler = (object objRef) => MarshalInspectable.DisposeMarshaler((IObjectReference)objRef); + DisposeMarshaler = MarshalInspectable.DisposeMarshaler; DisposeAbi = (object box) => MarshalInspectable.DisposeAbi((IntPtr)box); CreateMarshalerArray = (T[] array) => MarshalInspectable.CreateMarshalerArray(array); GetAbiArray = (object box) => MarshalInspectable.GetAbiArray(box); diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net5.0.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net5.0.txt index d89e041e2..e60f2d293 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net5.0.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net5.0.txt @@ -33,11 +33,9 @@ MembersMustExist : Member 'public T WinRT.MarshalDelegate.FromAbi(System.IntP MembersMustExist : Member 'public WinRT.ObjectReferenceValue WinRT.MarshalInspectable.CreateMarshaler2(T, System.Boolean)' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public WinRT.ObjectReferenceValue WinRT.MarshalInspectable.CreateMarshaler2(T, System.Guid, System.Boolean)' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public WinRT.IObjectReference WinRT.MarshalInspectable.CreateMarshaler(T, System.Guid, System.Boolean)' does not exist in the reference but it does exist in the implementation. -MembersMustExist : Member 'public WinRT.MarshalInterfaceHelper.MarshalerArray WinRT.MarshalInspectable.CreateMarshalerArray2(T[])' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public void WinRT.MarshalInspectable.DisposeMarshaler(WinRT.ObjectReferenceValue)' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public System.IntPtr WinRT.MarshalInspectable.GetAbi(WinRT.ObjectReferenceValue)' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public WinRT.ObjectReferenceValue WinRT.MarshalInterface.CreateMarshaler2(T, System.Guid)' does not exist in the reference but it does exist in the implementation. -MembersMustExist : Member 'public WinRT.MarshalInterfaceHelper.MarshalerArray WinRT.MarshalInterface.CreateMarshalerArray2(T[])' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public void WinRT.MarshalInterface.DisposeMarshaler(WinRT.ObjectReferenceValue)' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public System.IntPtr WinRT.MarshalInterface.GetAbi(WinRT.ObjectReferenceValue)' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public WinRT.MarshalInterfaceHelper.MarshalerArray WinRT.MarshalInterfaceHelper.CreateMarshalerArray2(T[], System.Func)' does not exist in the reference but it does exist in the implementation. @@ -51,4 +49,4 @@ TypesMustExist : Type 'WinRT.MarshalString.Pinnable' does not exist in the refer TypesMustExist : Type 'WinRT.ObjectReferenceValue' 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. -Total Issues: 52 +Total Issues: 50 \ No newline at end of file diff --git a/src/WinRT.Runtime/Projections/KeyValuePair.cs b/src/WinRT.Runtime/Projections/KeyValuePair.cs index 4300aea62..ff14e16f6 100644 --- a/src/WinRT.Runtime/Projections/KeyValuePair.cs +++ b/src/WinRT.Runtime/Projections/KeyValuePair.cs @@ -68,10 +68,7 @@ internal static unsafe void CopyManaged(global::System.Collections.Generic.KeyVa } internal static MarshalInterfaceHelper>.MarshalerArray CreateMarshalerArray(global::System.Collections.Generic.KeyValuePair[] array) => - MarshalInterfaceHelper>.CreateMarshalerArray(array, (o) => CreateMarshaler(o)); - - internal static MarshalInterfaceHelper>.MarshalerArray CreateMarshalerArray2(global::System.Collections.Generic.KeyValuePair[] array) => - MarshalInterfaceHelper>.CreateMarshalerArray2(array, (o) => CreateMarshaler2(o)); + MarshalInterfaceHelper>.CreateMarshalerArray2(array, (o) => CreateMarshaler2(o)); internal static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper>.GetAbiArray(box); diff --git a/src/WinRT.Runtime/TypeExtensions.cs b/src/WinRT.Runtime/TypeExtensions.cs index 23c0a6a68..edaf2c9d7 100644 --- a/src/WinRT.Runtime/TypeExtensions.cs +++ b/src/WinRT.Runtime/TypeExtensions.cs @@ -81,7 +81,10 @@ public static Type GetAbiType(this Type type) public static Type GetMarshalerType(this Type type) { - return type.GetHelperType().GetMethod("CreateMarshaler", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).ReturnType; + var helperType = type.GetHelperType(); + var createMarshaler = helperType.GetMethod("CreateMarshaler2", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static) ?? + helperType.GetMethod("CreateMarshaler", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + return createMarshaler.ReturnType; } internal static Type GetMarshalerArrayType(this Type type) diff --git a/src/cswinrt/code_writers.h b/src/cswinrt/code_writers.h index 94d85cc39..d79fd6af0 100644 --- a/src/cswinrt/code_writers.h +++ b/src/cswinrt/code_writers.h @@ -3354,7 +3354,7 @@ event % %;)", { w.write("% = %.GetAbi%(%);\n", get_param_local(w), - is_marshal_by_object_reference_value() && !is_array() ? "MarshalInspectable" : marshaler_type, + is_marshal_by_object_reference_value() ? "MarshalInspectable" : marshaler_type, is_array() ? "Array" : "", get_marshaler_local(w)); } @@ -3440,7 +3440,7 @@ event % %;)", } w.write("%.GetAbi%(%%)", - is_marshal_by_object_reference_value() && !is_array() ? "MarshalInspectable" : marshaler_type, + is_marshal_by_object_reference_value() ? "MarshalInspectable" : marshaler_type, is_array() ? "Array" : "", is_pinnable ? "ref " : "", get_marshaler_local(w)); @@ -3557,7 +3557,7 @@ event % %;)", else { w.write("%.DisposeMarshaler%(%);\n", - is_marshal_by_object_reference_value() && !is_array() ? "MarshalInspectable" : marshaler_type, + is_marshal_by_object_reference_value() ? "MarshalInspectable" : marshaler_type, is_array() ? "Array" : "", get_marshaler_local(w)); } @@ -3613,37 +3613,37 @@ event % %;)", break; case category::interface_type: m.marshaler_type = "MarshalInterface<" + m.param_type + ">"; - m.marshal_by_object_reference_value = true; if (m.is_array()) { m.local_type = w.write_temp("MarshalInterfaceHelper<%>.MarshalerArray", m.param_type); } else { + m.marshal_by_object_reference_value = true; m.local_type = m.is_out() ? "IntPtr" : "ObjectReferenceValue"; } break; case category::class_type: m.marshaler_type = w.write_temp("%", bind(semantics, typedef_name_type::ABI, true)); - m.marshal_by_object_reference_value = true; if (m.is_array()) { m.local_type = w.write_temp("MarshalInterfaceHelper<%>.MarshalerArray", m.param_type); } else { + m.marshal_by_object_reference_value = true; m.local_type = m.is_out() ? "IntPtr" : "ObjectReferenceValue"; } break; case category::delegate_type: m.marshaler_type = get_abi_type(); - m.marshal_by_object_reference_value = true; if (m.is_array()) { m.local_type = w.write_temp("MarshalInterfaceHelper<%>.MarshalerArray", m.param_type); } else { + m.marshal_by_object_reference_value = true; m.local_type = m.is_out() ? "IntPtr" : "ObjectReferenceValue"; } break; @@ -3654,13 +3654,13 @@ event % %;)", [&](object_type) { m.marshaler_type = "MarshalInspectable"; - m.marshal_by_object_reference_value = true; if (m.is_array()) { m.local_type = "MarshalInterfaceHelper.MarshalerArray"; } else { + m.marshal_by_object_reference_value = true; m.local_type = m.is_out() ? "IntPtr" : "ObjectReferenceValue"; } }, @@ -6538,8 +6538,7 @@ global::System.Collections.Concurrent.ConcurrentDictionary value is null ? IntPtr.Zero : MarshalInterfaceHelper.GetAbi(value); public static % FromAbi(IntPtr thisPtr) => %.FromAbi(thisPtr); public static IntPtr FromManaged(% obj) => obj is null ? IntPtr.Zero : CreateMarshaler2(obj).Detach(); -public static unsafe MarshalInterfaceHelper<%>.MarshalerArray CreateMarshalerArray(%[] array) => MarshalInterfaceHelper<%>.CreateMarshalerArray(array, (o) => CreateMarshaler(o)); -public static unsafe MarshalInterfaceHelper<%>.MarshalerArray CreateMarshalerArray2(%[] array) => MarshalInterfaceHelper<%>.CreateMarshalerArray2(array, (o) => CreateMarshaler2(o)); +public static unsafe MarshalInterfaceHelper<%>.MarshalerArray CreateMarshalerArray(%[] array) => MarshalInterfaceHelper<%>.CreateMarshalerArray2(array, (o) => CreateMarshaler2(o)); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper<%>.GetAbiArray(box); public static unsafe %[] FromAbiArray(object box) => MarshalInterfaceHelper<%>.FromAbiArray(box, FromAbi); public static (int length, IntPtr data) FromManagedArray(%[] array) => MarshalInterfaceHelper<%>.FromManagedArray(array, (o) => FromManaged(o)); @@ -6600,9 +6599,6 @@ public static ObjectReferenceValue CreateMarshaler2(% obj) => MarshalInterface<% projected_type_name, projected_type_name, projected_type_name, - projected_type_name, - projected_type_name, - projected_type_name, projected_type_name); }