一、字节数组转化成结构体
1)定义结构体
/// <summary>
/// 终端信息
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct TerminalInfo
{
/// <summary>
/// IP
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
public string Ip;
/// <summary>
/// 命令端口号
/// </summary>
public int CommandPort;
/// <summary>
/// 数据端口号
/// </summary>
public int DataPort;
/// <summary>
/// 连接状态 0掉线,1:在线
/// </summary>
public byte Status;
/// <summary>
/// 端口状态
/// 每一个字节对应一个端口的状态:
/// 0 该端口没有发现有设备
/// 1 该端口有设备,处于空闲状态
/// 2 该端口有设备,控制权已给其他计算机给获取
/// 有效数据不超过【usb端口总数】
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] PortsStatus;
}
2)字节数组转化成结构体
public static T BytesToStuct<T>(byte[] bytes) where T : struct
{
var t = new T();
/*1.字节数组转结构体*/
var size = Marshal.SizeOf(t);
if (size > bytes.Length)
{
return (default(T));
}
IntPtr structPtr = Marshal.AllocHGlobal(size);
Marshal.Copy(bytes, 0, structPtr, size);
var obj = Marshal.PtrToStructure(structPtr, t.GetType());
Marshal.FreeHGlobal(structPtr);
/*2.字节序转换*/
var type = typeof(T);
foreach (var field in type.GetFields())
{
if (field.FieldType == typeof(int))
{
var int32 = (int)field.GetValue(obj);
int32 = int32.FromBigEndian();
field.SetValue(obj, int32);
}
else if (field.FieldType == typeof(short))
{
var int16 = (short)field.GetValue(obj);
int16 = int16.FromBigEndian();
field.SetValue(obj, int16);
}
}
return (T)obj;
}
二、结构体转化成字节数组
//结构体转化成字节数组
public static byte[] StructToBytes(object structObj,int size)
{
StructDemo sd;
int num = 2;
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);
return bytes;
}