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 _);
}
}