在寫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;
- }