namespace Vanara.InteropServices; /// Functions to safely convert a memory pointer to a type. public static class IntPtrConverter { /// Converts the specified pointer to . /// The destination type. /// The pointer to a block of memory. /// The size of the allocated memory block. /// The character set. /// A value of the type specified. public static T? Convert(this IntPtr ptr, uint sz, CharSet charSet = CharSet.Auto) => (T?)Convert(ptr, sz, typeof(T), charSet); /// Converts the specified pointer to . /// The destination type. /// A block of allocated memory. /// The character set. /// A value of the type specified. public static T? ToType(this SafeAllocatedMemoryHandle hMem, CharSet charSet = CharSet.Auto) { if (hMem is null) throw new ArgumentNullException(nameof(hMem)); hMem.Lock(); try { return Convert(hMem.DangerousGetHandle(), hMem.Size, charSet); } finally { hMem.Unlock(); } } /// Converts the specified pointer to type specified in . /// The pointer to a block of memory. /// The size of the allocated memory block. /// The destination type. /// The character set. /// A value of the type specified. /// Cannot convert a null pointer. - ptr or Cannot convert a pointer with no Size. - sz /// Thrown if type cannot be converted from memory. /// public static object? Convert(this IntPtr ptr, uint sz, Type destType, CharSet charSet = CharSet.Auto) { if (ptr == IntPtr.Zero) { if (!destType.IsValueType) return null; throw new NullReferenceException(); } if (sz == 0) throw new ArgumentException("Cannot convert a pointer with no Size.", nameof(sz)); // Handle byte array and string as special cases if (destType.IsArray && destType.GetElementType() == typeof(byte)) return ptr.ToByteArray((int)sz); if (destType == typeof(string)) return StringHelper.GetString(ptr, charSet, sz); return ptr.ToStructure(destType, sz, 0, out _); } }