C#で上位計算機を開発する場合、バイトストリームと構造体の変換が必要となる場合が多いですが、以下のコードは構造体とバイトの変換のサンプルコードです。
public static byte[] StructToBytes<T>(T obj)
{
int size = Marshal.SizeOf(typeof(T));
IntPtr bufferPtr = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(obj, bufferPtr, false);
byte[] bytes = new byte[size];
Marshal.Copy(bufferPtr, bytes, 0, size);
return bytes;
}
catch (Exception ex)
{
throw new Exception("Error in StructToBytes ! " + ex.Message);
}
finally
{
Marshal.FreeHGlobal(bufferPtr);
}
}
public static object BytesToStuct(byte[] bytes, Type type)
{
//得到结构体的大小
int size = Marshal.SizeOf(type);
//byte数组长度小于结构体的大小
if (size > bytes.Length)
{
//返回空
return null;
}
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将byte数组拷到分配好的内存空间
Marshal.Copy(bytes, 0, structPtr, size);
//将内存空间转换为目标结构体
object obj = Marshal.PtrToStructure(structPtr, type);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回结构体
return obj;
}
public struct desc_info_t
{
public uint magic_num; //allways be 0x20200710
public uint size; //file size
public uint file_type; //file type
public uint method; //(reserve)differential upgrade
public uint chk_sum; //check sum, for ota
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)]
public byte[] device; //device name, such as "UE-E210"
}
public struct header_t
{
public uint prefix; //prefix: 0x20200655(LSB must 0x55)
public uint ver; //version of upgrade protocal
public uint baudrate; //auto switch baudrate
public uint en_485; //RS485 enable 0: disable 1: enable
public uint broadcast; //骞挎挱
public desc_info_t info; //file descriptor
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 60)]
public byte[] path;
}