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