如果能將 struct 變數 執行個體轉換成byte [] 類型,則可以方便我們將變數儲存傳遞壓縮等。以下是我的一個初步實現。
using System.Runtime.InteropServices;#region 需要轉換的結構 [StructLayout(LayoutKind.Sequential, Pack=1)]//struTest變數在記憶體中的對齊 (指標類型轉換成功的必要條件) public struct struTest{ public int intId; public int intName; public DateTime dtBegintime; } #endregion/// <summary> /// xamConverter 的摘要說明。 特定結構變數和byte[]之間的轉換操作 /// author:xam /// date:2007-4-23 /// note:apply convertion functions to deal with convertion between struct value and byte [] value; /// </summary> public class xamConverter { #region 建構函式 public xamConverter() { // // TODO: 在此處添加建構函式邏輯 // } #endregion #region 方式一 通過指標類型的強制轉換 #region 結構變數到byte[]的轉換 /// <summary> /// 結構變數到byte[]的轉換 /// </summary> /// <param name="s">結構變數</param> /// <returns>byte[](已指派空間)</returns> public unsafe byte[] xamStructToBytes( struTest s ) { byte[] arr = new byte[ sizeof(struTest) ]; fixed( byte* parr = arr ) { *((struTest*)parr) = s; } return arr; } #endregion #region byte[] 到結構變數的轉換 /// <summary> /// byte[] 到結構變數的轉換 /// </summary> /// <param name="arr">byte[]</param> /// <returns>結構變數</returns> public unsafe struTest xamBytesToStruct( byte[] arr ) { if( arr.Length < sizeof(struTest) ) throw new ArgumentException(); struTest s; fixed( byte* parr = arr ) { s = *((struTest*)parr); } return s; } #endregion #region 結構變數數組到byte[]的轉換 /// <summary> /// 結構變數數組到byte[]的轉換 /// </summary> /// <param name="s">結構變數數組</param> /// <param name="tSize">結構變數數組的大小</param> /// <returns>byte[]</returns> public unsafe byte[] xamStructToBytes( struTest[] s,int tSize ) { int i; byte[] arr = new byte[ sizeof(struTest)*tSize ]; for(i=0;i<tSize;i++){ fixed( byte* parr = arr ) { (((struTest*)parr)[i]) = s[i]; } } return arr; } #endregion #region byte[] 到結構變數數組的轉換 /// <summary> /// byte[] 到結構變數數組的轉換 /// </summary> /// <param name="arr">byte[]</param> /// <param name="tSize">byte[]包含的結構變數數組的大小</param> /// <returns></returns> public unsafe struTest[] xamBytesToStruct( byte[] arr,int tSize ) { if( arr.Length < sizeof(struTest)*tSize ) throw new ArgumentException(); int i; struTest[] s = new struTest[tSize]; for(i=0;i<tSize;i++){ fixed( byte* parr = arr ) { s[i] = (((struTest*)parr)[i]); } } return s; } #endregion #endregion #region 方式二 #region 結構變數到byte[]的轉換 /// <summary> /// 結構變數到byte[]的轉換 /// </summary> /// <param name="s">結構變數</param> /// <returns>byte[](已指派空間)</returns> public unsafe byte[] xamStructToBytesB( struTest s ) { int size = Marshal.SizeOf(s); System.IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(s, ptr,true); byte[] ba=new byte[size]; Marshal.Copy(ptr, ba, 0, ba.Length ); return ba; } #endregion #region byte[] 到結構變數的轉換 /// <summary> /// byte[] 到結構變數的轉換 /// </summary> /// <param name="arr">byte[]</param> /// <returns>結構變數</returns> public unsafe struTest xamBytesToStructB( byte[] arr ) { struTest struReturn=new struTest(); int size = Marshal.SizeOf(struReturn); System.IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.Copy(arr,0,ptr,arr.Length); struReturn = (struTest)Marshal.PtrToStructure(ptr,struReturn.GetType()); return struReturn; } #endregion #region 結構變數數組到byte[]的轉換 /// <summary> /// 結構變數數組到byte[]的轉換 /// </summary> /// <param name="s">結構變數數組</param> /// <param name="tSize">結構變數數組的大小</param> /// <returns>byte[]</returns> public unsafe byte[] xamStructToBytesB( struTest[] s,int tSize ) { int i; int size = Marshal.SizeOf(s[0])*s.Length; System.IntPtr [] ptrs = new IntPtr[s.Length]; for(i=0;i<tSize;i++){ ptrs[i] = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(s[i], ptrs[i],true); } byte[] ba=new byte[size]; for(i=0;i<tSize;i++){ Marshal.Copy(ptrs[i], ba, i*Marshal.SizeOf(s[0]), Marshal.SizeOf(s[0]) ); } return ba; } #endregion #region byte[] 到結構變數數組的轉換 /// <summary> /// byte[] 到結構變數數組的轉換 /// </summary> /// <param name="arr">byte[]</param> /// <param name="tSize">byte[]包含的結構變數數組的大小</param> /// <returns></returns> public unsafe struTest[] xamBytesToStructB( byte[] arr,int tSize ) { if( arr.Length < sizeof(struTest)*tSize ) throw new ArgumentException(); struTest[] struReturn=new struTest[tSize]; int intUnitSize = Marshal.SizeOf(struReturn[0]); int size = intUnitSize*tSize; int i;int intTemp; System.IntPtr [] ptrs = new IntPtr[tSize]; for(i=0;i<tSize;i++){ intTemp = i*intUnitSize; ptrs[i] = Marshal.AllocHGlobal(size); Marshal.Copy(arr,intTemp,ptrs[i],intUnitSize); struReturn[i] = (struTest)Marshal.PtrToStructure(ptrs[i],struReturn[i].GetType()); } return struReturn; } #endregion #endregion }
使用unsafe code 不安全的程式碼選項需開啟
示範
#region 結構數組測試 xamConverter xc = new xamConverter(); struTest[] st = new struTest[3]; st[0].intId = 1; st[0].intName = 12; st[0].dtBegintime = DateTime.Now; st[2].intId = 2; st[2].intName = 232; st[2].dtBegintime = DateTime.Now; byte [] inputBytes = xc.xamStructToBytesB(st,3); struTest[] st2 = xc.xamBytesToStructB(inputBytes,3); MessageBox.Show(st2[2].dtBegintime.ToString() + " = " + st2[2].intName.ToString()); #endregion