习惯了C和C++中的简单 直接 暴力的强制类型转换,过度到C#这种更加高级的语言中有些不适应啊,高
级语言带来好处的同时(比如GC机制)也带来了一些不方便的特性,比如PC端使用串口向我发了一包完
整的结构体数据,我使用C#所做的上位机将数据都接受下来了,但解析数据是个很麻烦的过程,尤其是
数据量大的时候,此时不禁想起如果C# 能够向C或C++一样强转一块内存为结构体类型该多好
添加引用命名空间
using System.Runtime.InteropServices;
代码实现
Byte[]转Struct
public static T ByteToStructure<T>(Byte[] dataBuffer)
{
object structure = null;
int size = Marshal.SizeOf(typeof(T));
IntPtr allocIntPtr = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(dataBuffer, 0, allocIntPtr, size);
structure = Marshal.PtrToStructure(allocIntPtr, typeof(T));
}
finally
{
Marshal.FreeHGlobal(allocIntPtr);
}
return (T)structure;
}
Struct转Byte[]
public static byte[] StructToBytes(object structObj)
{
//得到结构体的大小
int size = Marshal.SizeOf(structObj);
//创建byte数组
byte[] bytes = new byte[size];
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将结构体拷到分配好的内存空间
Marshal.StructureToPtr(structObj, structPtr, false);
//从内存空间拷到byte数组
Marshal.Copy(structPtr, bytes, 0, size);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回byte数组
return bytes;
}
注意Struct字节对齐
如下代码定义的Struct,4字节对齐
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct ONE_BOARD_DATA
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public Byte[] b1;
public Byte IOStatus;
public Byte bHint;//1:debug message 0:none
public Byte HintMsgLen;
public UInt16 HintReserved; // u16 Hint保留位
public UInt32 crc; //u32
};