using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using Vanara.Extensions; namespace Vanara.InteropServices { /// Marshals strings that are allocated by native code and must be freed using CoTaskMemFree after use. /// public class CoTaskMemStringMarshaler : ICustomMarshaler { private CharSet charSet = CharSet.Unicode; /// Gets the instance. /// The cookie. /// public static ICustomMarshaler GetInstance(string cookie) { var ret = new CoTaskMemStringMarshaler(); if (!string.IsNullOrEmpty(cookie)) { try { ret.charSet = (CharSet) Enum.Parse(typeof(CharSet), cookie, true); } catch { } } return ret; } internal CharSet CharSet => charSet; /// Performs necessary cleanup of the managed data when it is no longer needed. /// The managed object to be destroyed. public void CleanUpManagedData(object ManagedObj) { } /// Performs necessary cleanup of the unmanaged data when it is no longer needed. /// A pointer to the unmanaged data to be destroyed. public void CleanUpNativeData(IntPtr pNativeData) { StringHelper.FreeString(pNativeData, charSet); } /// Returns the size of the native data to be marshaled. /// The size in bytes of the native data. public int GetNativeDataSize() => IntPtr.Size; /// Converts the managed data to unmanaged data. /// The managed object to be converted. /// Returns the COM view of the managed object. public IntPtr MarshalManagedToNative(object ManagedObj) => StringHelper.AllocString(ManagedObj as string, charSet); /// Converts the unmanaged data to managed data. /// A pointer to the unmanaged data to be wrapped. /// Returns the managed view of the COM data. public object MarshalNativeToManaged(IntPtr pNativeData) => StringHelper.GetString(pNativeData, charSet); } }