https://blog.csdn.net/liuxf196921/article/details/21555541
在寫C#TCP通信程序時,發送數據時,只能發送byte數組,處理起來比較麻煩不說,如果是和VC6.0等寫的程序通信的話,很多的都是傳送結構體,在VC6.0中可以很方便的把一個char[]數組轉換為一個結構體,而在C#卻不能直接把byte數組轉換為結構體,要在C#中發送結構體,可以按以下方法實現:
(1)定義結構體:
//命名空間
using System.Runtime.InteropServices;
//注意這個屬性不能少
[StructLayoutAttribute(LayoutKind.Sequential,CharSet=CharSet.Ansi,Pack=1)]
struct TestStruct
...{
public int c;
//字符串,SizeConst為字符串的最大長度
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string str;
//int數組,SizeConst表示數組的個數,在轉換成
//byte數組前必須先初始化數組,再使用,初始化
//的數組長度必須和SizeConst一致,例test = new int[6];
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public int[] test;
}
(2)結構體轉byte數組:
/**//// <summary>
/// 結構體轉byte數組
/// </summary>
/// <param name="structObj">要轉換的結構體</param>
/// <returns>轉換后的byte數組</returns>
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;
}
(3)byte數組轉結構體:
/**//// <summary>
/// byte數組轉結構體
/// </summary>
/// <param name="bytes">byte數組</param>
/// <param name="type">結構體類型</param>
/// <returns>轉換后的結構體</returns>
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;
}