您的位置:首页 > 编程语言 > C#

c# 结构体struct包含数与byte类型的转换(一)

2012-05-05 19:03 471 查看
对与c#中结构体 struct 和byte类型的数组之间的相互转换可以参照 http://kb.cnblogs.com/a/1685137/
代码贴在下面

注 在使用之前要设置编译器可以使用unsafe的状态 可以参考 http://blog.csdn.net/csskysea/article/details/6970402


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
以上的实现相对比较简单,但是很多时候结构体不是那个样子的

比如

public  struct struTest
{ public int[] data;
public int[] fft;
};


按照上面的结构体带到刚才的代码中是回报错的:不能访问托管对象、不能得到结构体的大小
Marshal.SizeOf();函数会报错


而c#又不允许在结构体内部定义数组的大小,所以恢搞的很头痛。。。。。。。。。

下一篇继续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: