using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using Vanara.Extensions; using Vanara.InteropServices; using Vanara.PInvoke; namespace Vanara.PInvoke { public static partial class Kernel32 { /// A for memory allocated as moveable HGLOBAL. /// public class SafeMoveableHGlobalHandle : SafeMemoryHandleExt { /// Initializes a new instance of the class. /// The handle. /// if set to true if this class is responsible for freeing the memory on disposal. public SafeMoveableHGlobalHandle(IntPtr handle, bool ownsHandle = true) : base(handle, handle == default ? 0 : GlobalSize(handle), ownsHandle) { } /// Initializes a new instance of the class. /// The size of memory to allocate, in bytes. /// size - The value of this argument must be non-negative public SafeMoveableHGlobalHandle(SizeT size) : base(size) { } /// /// Allocates from unmanaged memory to represent an array of pointers and marshals the unmanaged pointers (IntPtr) to the native /// array equivalent. /// /// Array of unmanaged pointers /// SafeMoveableHGlobalHandle object to an native (unmanaged) array of pointers public SafeMoveableHGlobalHandle(byte[] bytes) : base(bytes?.Length ?? 0) { if (Size == 0) return; CallLocked(p => Marshal.Copy(bytes, 0, p, sz)); } /// /// Initializes a new instance of the class from a /// instance, copying all the memory. /// /// The source memory block. public SafeMoveableHGlobalHandle(SafeAllocatedMemoryHandle source) : base(source) { } /// Initializes a new instance of the class. [ExcludeFromCodeCoverage] internal SafeMoveableHGlobalHandle() : base(0) { } /// Represents a NULL memory pointer. public static SafeMoveableHGlobalHandle Null { get; } = new SafeMoveableHGlobalHandle(IntPtr.Zero, false); /// /// Allocates from unmanaged memory to represent a structure with a variable length array at the end and marshal these structure /// elements. It is the callers responsibility to marshal what precedes the trailing array into the unmanaged memory. ONLY /// structures with attribute StructLayout of LayoutKind.Sequential are supported. /// /// Type of the trailing array of structures /// Collection of structure objects /// Number of bytes preceding the trailing array of structures /// object to an native (unmanaged) structure with a trail array of structures public static SafeMoveableHGlobalHandle CreateFromList(IEnumerable values, int prefixBytes = 0) => new(InteropExtensions.MarshalToPtr(values, mm.AllocMem, out _, prefixBytes, mm.LockMem, mm.UnlockMem), true); /// Allocates from unmanaged memory sufficient memory to hold an array of strings. /// The list of strings. /// The packing type for the strings. /// The character set to use for the strings. /// Number of bytes preceding the trailing strings. /// /// object to an native (unmanaged) array of strings stored using the model and the character set defined by . /// public static SafeMoveableHGlobalHandle CreateFromStringList(IEnumerable values, StringListPackMethod packing = StringListPackMethod.Concatenated, CharSet charSet = CharSet.Auto, int prefixBytes = 0) => new(InteropExtensions.MarshalToPtr(values, packing, mm.AllocMem, out _, charSet, prefixBytes, mm.LockMem, mm.UnlockMem), true); /// Allocates from unmanaged memory sufficient memory to hold an object of type T. /// Native type /// The value. /// object to an native (unmanaged) memory block the size of T. public static SafeMoveableHGlobalHandle CreateFromStructure(in T value = default) => new(InteropExtensions.MarshalToPtr(value, mm.AllocMem, out _, 0, mm.LockMem, mm.UnlockMem), true); /// Converts an to a where it owns the reference. /// The . /// The result of the conversion. public static implicit operator SafeMoveableHGlobalHandle(IntPtr ptr) => new(ptr, true); } } }