I know that you can use code like this to marshal a structure into a byte array:
public static byte[] StructureToByteArray(object obj)
{
int len = Marshal.SizeOf(obj);
byte[] arr = new byte[len];
IntPtr ptr = Marshal.AllocHGlobal(len);
Marshal.StructureToPtr(obj, ptr, true);
Marshal.Copy(ptr, arr, 0, len);
Marshal.FreeHGlobal(ptr);
return arr;
}
But how do you marshal a structure into an array containing 16 bit words instead of bytes?
public static UInt16[] StructureToUInt16Array(object obj)
{
// What to do?
}
The Unsafe and the Safe way to do this:
static UInt16[] MarshalUInt16(Object obj)
{
int len = Marshal.SizeOf(obj);
IntPtr ptr = Marshal.AllocHGlobal(len);
Marshal.StructureToPtr(obj, ptr, true);
UInt16[] arr = new UInt16[len / 2];
unsafe
{
UInt16* csharpPtr = (UInt16*)ptr;
for (Int32 i = 0; i < arr.Length; i++)
{
arr[i] = csharpPtr[i];
}
}
Marshal.FreeHGlobal(ptr);
return arr;
}
static UInt16[] SafeMarshalUInt16(Object obj)
{
int len = Marshal.SizeOf(obj);
byte[] buf = new byte[len];
IntPtr ptr = Marshal.AllocHGlobal(len);
Marshal.StructureToPtr(obj, ptr, true);
Marshal.Copy(ptr, buf, 0, len);
Marshal.FreeHGlobal(ptr);
UInt16[] arr = new UInt16[len / 2];
//for (Int32 i = 0; i < arr.Length; i++)
//{
// arr[i] = BitConverter.ToUInt16(buf, i * 2);
//}
Buffer.BlockCopy(buf, 0, arr, 0, len);
return arr;
}
Updated to reflect the wisdom of others.
Any reason not to marshal into a byte array and then use Buffer.BlockCopy
? That would be the simplest approach, I'd say. Admittedly you do have to do appropriate copying, so it's less efficient, but I don't think you'll find a much simpler way.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.