c# struct 變量 到 byte[] 變量的轉換操作

如果能將 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




發佈了6 篇原創文章 · 獲贊 15 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章