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