diff --git a/Core/InteropServices/VanaraMarshaler.cs b/Core/InteropServices/VanaraMarshaler.cs index 9d2f6de8..125f9a79 100644 --- a/Core/InteropServices/VanaraMarshaler.cs +++ b/Core/InteropServices/VanaraMarshaler.cs @@ -27,40 +27,6 @@ namespace Vanara.InteropServices object MarshalNativeToManaged(IntPtr pNativeData, SizeT allocatedBytes); } - [VanaraMarshaler(typeof(TestMarshal))] - internal struct TestMarshal : IVanaraMarshaler - { - public bool bVal; - public uint[] uArray; - - SizeT IVanaraMarshaler.GetNativeSize() => 12; - - SafeAllocatedMemoryHandle IVanaraMarshaler.MarshalManagedToNative(object managedObject) - { - if (managedObject is null) return SafeHGlobalHandle.Null; - if (!(managedObject is TestMarshal t)) - throw new ArgumentException($"Object must be a {nameof(TestMarshal)} instance.", nameof(managedObject)); - var mem = new SafeHGlobalHandle(12); - mem.Write(t.bVal ? 1U : 0U); - mem.Write(t.uArray?.Length ?? 0); - mem.Write(t.uArray, true, 8); - return mem; - } - - object IVanaraMarshaler.MarshalNativeToManaged(IntPtr pNativeData, SizeT allocatedBytes) - { - var ret = default(TestMarshal); - if (pNativeData != IntPtr.Zero) - { - using var str = new NativeMemoryStream(pNativeData, allocatedBytes); - ret.bVal = str.Read() != 0; - var len = str.Read(); - ret.uArray = str.ReadArray(len, false).ToArray(); - } - return ret; - } - } - /// Provides methods to assist with custom marshaling. public static class VanaraMarshaler { @@ -73,7 +39,10 @@ namespace Vanara.InteropServices var vattr = t.GetCustomAttributes(true).FirstOrDefault(); if (vattr != null) { - marshaler = Activator.CreateInstance(vattr.MarshalType) as IVanaraMarshaler; + var cookie = vattr.Cookie; + marshaler = cookie is null ? + Activator.CreateInstance(vattr.MarshalType) as IVanaraMarshaler : + Activator.CreateInstance(vattr.MarshalType, cookie) as IVanaraMarshaler; return marshaler != null; } if (typeof(IVanaraMarshaler).IsAssignableFrom(t)) @@ -100,10 +69,9 @@ namespace Vanara.InteropServices public class VanaraCustomMarshaler : ICustomMarshaler { private SafeAllocatedMemoryHandle mem; + private readonly string cookie; - private VanaraCustomMarshaler(string _) - { - } + private VanaraCustomMarshaler(string cookie) => this.cookie = cookie; /// Gets the instance. /// The cookie. @@ -130,15 +98,22 @@ namespace Vanara.InteropServices { /// Initializes a new instance of the class. /// A type that derives from that will marshal this class or structure. - public VanaraMarshalerAttribute(Type marshalType) + /// The cookie value to pass to the constructor. + /// marshalType + /// The supplied type must inherit from {nameof(IVanaraMarshaler)}. - marshalType + public VanaraMarshalerAttribute(Type marshalType, string cookie = null) { if (marshalType is null) throw new ArgumentNullException(nameof(marshalType)); if (!typeof(IVanaraMarshaler).IsAssignableFrom(marshalType)) throw new ArgumentException($"The supplied type must inherit from {nameof(IVanaraMarshaler)}.", nameof(marshalType)); MarshalType = marshalType; + Cookie = cookie; } + /// Gets the cookie value, that if not , will get passed to the constructor of . + public string Cookie { get; } + /// Gets the type that will marshal this class or structure. public Type MarshalType { get; } }