Skip to content

Commit

Permalink
Fix storage buffer specific IMarshal interface by updating it to new …
Browse files Browse the repository at this point in the history
…interface format (#930)

* Updating buffer specific IMarshal interface to unmanaged callers type interface

* Move IBufferByteAccess to new format.

* Converting a couple more functions to unmanaged calers.
  • Loading branch information
manodasanW authored Jul 27, 2021
1 parent 4560924 commit 75ffe54
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 143 deletions.
5 changes: 0 additions & 5 deletions src/WinRT.Runtime/Interop/IMarshal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,6 @@ internal static Guid GetInProcFreeThreadedMarshalerIID()
t_freeThreadedMarshaler.GetUnmarshalClass(&iid_IUnknown, IntPtr.Zero, MSHCTX.InProc, IntPtr.Zero, MSHLFLAGS.Normal, &iid_unmarshalClass);
return iid_unmarshalClass;
}

public Vftbl(IntPtr ptr)
{
this = Marshal.PtrToStructure<Vftbl>(ptr);
}

#if !NETSTANDARD2_0
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })]
Expand Down
42 changes: 28 additions & 14 deletions src/WinRT.Runtime/Projections/EventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using WinRT;
Expand Down Expand Up @@ -121,25 +122,32 @@ private static unsafe int Do_Abi_Invoke<TAbi>(void* thisPtr, IntPtr sender, TAbi
[Guid("c50898f6-c536-5f47-8583-8b2c2438a13b")]
internal static class EventHandler
{
#if NETSTANDARD2_0
private delegate int Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr args);
#endif

private static readonly global::WinRT.Interop.IDelegateVftbl AbiToProjectionVftable;
public static readonly IntPtr AbiToProjectionVftablePtr;

static EventHandler()
static unsafe EventHandler()
{
AbiInvokeDelegate = (Abi_Invoke)Do_Abi_Invoke;
AbiToProjectionVftable = new global::WinRT.Interop.IDelegateVftbl
{
IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl,
Invoke = Marshal.GetFunctionPointerForDelegate(AbiInvokeDelegate)
#if NETSTANDARD2_0
Invoke = Marshal.GetFunctionPointerForDelegate(AbiInvokeDelegate = (Abi_Invoke)Do_Abi_Invoke)
#else
Invoke = (IntPtr)(delegate* unmanaged[Stdcall]<IntPtr, IntPtr, IntPtr, int>)&Do_Abi_Invoke
#endif
};
var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(EventHandler), Marshal.SizeOf<global::WinRT.Interop.IDelegateVftbl>());
Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false);
AbiToProjectionVftablePtr = nativeVftbl;
}

}

#if NETSTANDARD2_0
public static global::System.Delegate AbiInvokeDelegate { get; }
#endif

public static unsafe IObjectReference CreateMarshaler(global::System.EventHandler managedDelegate) =>
managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, GuidGenerator.GetIID(typeof(EventHandler)));
Expand Down Expand Up @@ -174,27 +182,30 @@ public NativeDelegateWrapper(ObjectReference<global::WinRT.Interop.IDelegateVftb
ConcurrentDictionary<RuntimeTypeHandle, object> IWinRTObject.AdditionalTypeData { get; } = new();
#endif

public void Invoke(object sender, EventArgs args)
public unsafe void Invoke(object sender, EventArgs args)
{
IntPtr ThisPtr = _nativeDelegate.ThisPtr;
IntPtr ThisPtr = _nativeDelegate.ThisPtr;
#if NETSTANDARD2_0
var abiInvoke = Marshal.GetDelegateForFunctionPointer<Abi_Invoke>(_nativeDelegate.Vftbl.Invoke);
#else
var abiInvoke = (delegate* unmanaged[Stdcall]<IntPtr, IntPtr, IntPtr, int>)(_nativeDelegate.Vftbl.Invoke);
#endif
IObjectReference __sender = default;
IObjectReference __args = default;
var __params = new object[] { ThisPtr, null, null };
try
{
__sender = MarshalInspectable<object>.CreateMarshaler(sender);
__params[1] = MarshalInspectable<object>.GetAbi(__sender);
__args = MarshalInspectable<EventArgs>.CreateMarshaler(args);
__params[2] = MarshalInspectable<EventArgs>.GetAbi(__args);
abiInvoke.DynamicInvokeAbi(__params);
global::WinRT.ExceptionHelpers.ThrowExceptionForHR(abiInvoke(
ThisPtr,
MarshalInspectable<object>.GetAbi(__sender),
MarshalInspectable<EventArgs>.GetAbi(__args)));
}
finally
{
MarshalInspectable<object>.DisposeMarshaler(__sender);
MarshalInspectable<EventArgs>.DisposeMarshaler(__args);
}

}
}

Expand All @@ -203,8 +214,11 @@ public static IntPtr FromManaged(global::System.EventHandler managedDelegate) =>

public static void DisposeMarshaler(IObjectReference value) => MarshalInterfaceHelper<global::System.EventHandler<object>>.DisposeMarshaler(value);

public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper<global::System.EventHandler<object>>.DisposeAbi(abi);

public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper<global::System.EventHandler<object>>.DisposeAbi(abi);

#if !NETSTANDARD2_0
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })]
#endif
private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr args)
{
try
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using WinRT;
Expand All @@ -12,19 +13,24 @@ namespace ABI.System.Collections.Specialized
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
[Guid("8B0909DC-2005-5D93-BF8A-725F017BAA8D")]
public static class NotifyCollectionChangedEventHandler
{
{
#if NETSTANDARD2_0
private unsafe delegate int Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e);
#endif

private static readonly global::WinRT.Interop.IDelegateVftbl AbiToProjectionVftable;
public static readonly IntPtr AbiToProjectionVftablePtr;

static NotifyCollectionChangedEventHandler()
static unsafe NotifyCollectionChangedEventHandler()
{
AbiInvokeDelegate = new Abi_Invoke(Do_Abi_Invoke);
AbiToProjectionVftable = new global::WinRT.Interop.IDelegateVftbl
{
IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl,
Invoke = Marshal.GetFunctionPointerForDelegate(AbiInvokeDelegate)
IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl,
#if NETSTANDARD2_0
Invoke = Marshal.GetFunctionPointerForDelegate(AbiInvokeDelegate = (Abi_Invoke)Do_Abi_Invoke)
#else
Invoke = (IntPtr)(delegate* unmanaged[Stdcall]<IntPtr, IntPtr, IntPtr, int>)&Do_Abi_Invoke
#endif
};
var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(NotifyCollectionChangedEventHandler), Marshal.SizeOf<global::WinRT.Interop.IDelegateVftbl>());
Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false);
Expand Down Expand Up @@ -65,10 +71,14 @@ public NativeDelegateWrapper(ObjectReference<global::WinRT.Interop.IDelegateVftb
ConcurrentDictionary<RuntimeTypeHandle, object> IWinRTObject.AdditionalTypeData { get; } = new();
#endif

public void Invoke(object sender, global::System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
public unsafe void Invoke(object sender, global::System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
IntPtr ThisPtr = _nativeDelegate.ThisPtr;
IntPtr ThisPtr = _nativeDelegate.ThisPtr;
#if NETSTANDARD2_0
var abiInvoke = Marshal.GetDelegateForFunctionPointer<Abi_Invoke>(_nativeDelegate.Vftbl.Invoke);
#else
var abiInvoke = (delegate* unmanaged[Stdcall]<IntPtr, IntPtr, IntPtr, int>)(_nativeDelegate.Vftbl.Invoke);
#endif
IObjectReference __sender = default;
IObjectReference __e = default;
try
Expand All @@ -91,8 +101,11 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo

public static void DisposeMarshaler(IObjectReference value) => MarshalInterfaceHelper<global::System.Collections.Specialized.NotifyCollectionChangedEventHandler>.DisposeMarshaler(value);

public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper<global::System.Collections.Specialized.NotifyCollectionChangedEventHandler>.DisposeAbi(abi);

public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper<global::System.Collections.Specialized.NotifyCollectionChangedEventHandler>.DisposeAbi(abi);

#if !NETSTANDARD2_0
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })]
#endif
private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e)
{
try
Expand Down
33 changes: 22 additions & 11 deletions src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using WinRT;
Expand All @@ -11,19 +12,24 @@ namespace ABI.System.ComponentModel
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
[Guid("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D")]
public static class PropertyChangedEventHandler
{
{
#if NETSTANDARD2_0
private unsafe delegate int Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e);
#endif

private static readonly global::WinRT.Interop.IDelegateVftbl AbiToProjectionVftable;
public static readonly IntPtr AbiToProjectionVftablePtr;

static PropertyChangedEventHandler()
static unsafe PropertyChangedEventHandler()
{
AbiInvokeDelegate = new Abi_Invoke(Do_Abi_Invoke);
AbiToProjectionVftable = new global::WinRT.Interop.IDelegateVftbl
{
IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl,
Invoke = Marshal.GetFunctionPointerForDelegate(AbiInvokeDelegate)
IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl,
#if NETSTANDARD2_0
Invoke = Marshal.GetFunctionPointerForDelegate(AbiInvokeDelegate = (Abi_Invoke)Do_Abi_Invoke)
#else
Invoke = (IntPtr)(delegate* unmanaged[Stdcall]<IntPtr, IntPtr, IntPtr, int>)&Do_Abi_Invoke
#endif
};
var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(PropertyChangedEventHandler), Marshal.SizeOf<global::WinRT.Interop.IDelegateVftbl>());
Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false);
Expand Down Expand Up @@ -64,10 +70,14 @@ public NativeDelegateWrapper(ObjectReference<global::WinRT.Interop.IDelegateVftb
ConcurrentDictionary<RuntimeTypeHandle, object> IWinRTObject.AdditionalTypeData { get; } = new();
#endif

public void Invoke(object sender, global::System.ComponentModel.PropertyChangedEventArgs e)
public unsafe void Invoke(object sender, global::System.ComponentModel.PropertyChangedEventArgs e)
{
IntPtr ThisPtr = _nativeDelegate.ThisPtr;
IntPtr ThisPtr = _nativeDelegate.ThisPtr;
#if NETSTANDARD2_0
var abiInvoke = Marshal.GetDelegateForFunctionPointer<Abi_Invoke>(_nativeDelegate.Vftbl.Invoke);
#else
var abiInvoke = (delegate* unmanaged[Stdcall]<IntPtr, IntPtr, IntPtr, int>)(_nativeDelegate.Vftbl.Invoke);
#endif
IObjectReference __sender = default;
IObjectReference __e = default;
try
Expand All @@ -90,12 +100,13 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv

public static void DisposeMarshaler(IObjectReference value) => MarshalInterfaceHelper<global::System.ComponentModel.PropertyChangedEventHandler>.DisposeMarshaler(value);

public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper<global::System.ComponentModel.PropertyChangedEventHandler>.DisposeAbi(abi);

public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper<global::System.ComponentModel.PropertyChangedEventHandler>.DisposeAbi(abi);

#if !NETSTANDARD2_0
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })]
#endif
private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e)
{


try
{
global::WinRT.ComWrappersSupport.MarshalDelegateInvoke(thisPtr, (global::System.ComponentModel.PropertyChangedEventHandler invoke) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ internal interface IBufferByteAccess

namespace ABI.Windows.Storage.Streams
{
using global::System;
using global::System;
using global::System.Runtime.CompilerServices;
using global::System.Runtime.InteropServices;
using global::System.ComponentModel;

Expand Down Expand Up @@ -87,46 +88,33 @@ public IntPtr Buffer
#else
[DynamicInterfaceCastableImplementation]
[Guid("905a0fef-bc53-11df-8c49-001e4fc686da")]
internal interface IBufferByteAccess : global::Windows.Storage.Streams.IBufferByteAccess
internal unsafe interface IBufferByteAccess : global::Windows.Storage.Streams.IBufferByteAccess
{
[Guid("905a0fef-bc53-11df-8c49-001e4fc686da")]
public struct Vftbl
{
public delegate int _get_Buffer_0(IntPtr thisPtr, out IntPtr buffer);

{
internal global::WinRT.Interop.IUnknownVftbl IUnknownVftbl;
public _get_Buffer_0 get_Buffer_0;
public delegate* unmanaged[Stdcall]<IntPtr, IntPtr*, int> Get_Buffer_0;

public static readonly IntPtr AbiToProjectionVftablePtr;

static unsafe Vftbl()
{
AbiToProjectionVftable = new Vftbl
{
AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(Vftbl), Marshal.SizeOf<global::WinRT.Interop.IUnknownVftbl>() + sizeof(IntPtr) * 1);
(*(Vftbl*)AbiToProjectionVftablePtr) = new Vftbl
{
IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl,
get_Buffer_0 = Do_Abi_get_Buffer_0
Get_Buffer_0 = &Do_Abi_get_Buffer_0,
};
var nativeVftbl = (IntPtr*)Marshal.AllocCoTaskMem(Marshal.SizeOf<IUnknownVftbl>() + sizeof(IntPtr) * 12);
Marshal.StructureToPtr(AbiToProjectionVftable.IUnknownVftbl, (IntPtr)nativeVftbl, false);
nativeVftbl[3] = Marshal.GetFunctionPointerForDelegate(AbiToProjectionVftable.get_Buffer_0);
AbiToProjectionVftablePtr = (IntPtr)nativeVftbl;
}

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

internal unsafe Vftbl(IntPtr thisPtr)
{
var vftblPtr = Marshal.PtrToStructure<VftblPtr>(thisPtr);
var vftbl = (IntPtr*)vftblPtr.Vftbl;
IUnknownVftbl = Marshal.PtrToStructure<IUnknownVftbl>(vftblPtr.Vftbl);
get_Buffer_0 = Marshal.GetDelegateForFunctionPointer<_get_Buffer_0>(vftbl[3]);
}

private static int Do_Abi_get_Buffer_0(IntPtr thisPtr, out IntPtr buffer)
}

[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })]
private static int Do_Abi_get_Buffer_0(IntPtr thisPtr, IntPtr* buffer)
{
buffer = default;
*buffer = default;
try
{
buffer = ComWrappersSupport.FindObject<global::Windows.Storage.Streams.IBufferByteAccess>(thisPtr).Buffer;
*buffer = ComWrappersSupport.FindObject<global::Windows.Storage.Streams.IBufferByteAccess>(thisPtr).Buffer;
}
catch (Exception ex)
{
Expand All @@ -142,8 +130,9 @@ private static int Do_Abi_get_Buffer_0(IntPtr thisPtr, out IntPtr buffer)
get
{
var _obj = ((ObjectReference<Vftbl>)((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.Storage.Streams.IBufferByteAccess).TypeHandle));
var ThisPtr = _obj.ThisPtr;
Marshal.ThrowExceptionForHR(_obj.Vftbl.get_Buffer_0(ThisPtr, out IntPtr buffer));
var ThisPtr = _obj.ThisPtr;
IntPtr buffer = default;
Marshal.ThrowExceptionForHR(_obj.Vftbl.Get_Buffer_0(ThisPtr, &buffer));
return buffer;
}
}
Expand Down
Loading

0 comments on commit 75ffe54

Please sign in to comment.