结构体与byte数组的转换

// c# 实现

 

 1 // 这个属性不能少
 2 
 3 [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
 4 
 5 public struct StructArgs
 6 
 7 {
 8 
 9     public byte bUsed;
10 
11     public int userType;
12 
13     public int value;
14 
15     public long time;
16 
17     public int jointIdx;
18 
19  
20 
21     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
22 
23     public float[] begin;
24 
25  
26 
27     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
28 
29     public float[] end;
30 
31 };

 

 

StructLayoutAttribute 类使用户可以控制类或结构的数据字段的物理布局。

LayoutKind    Sequential 用于强制将成员按其出现的顺序进行顺序布局Explicit 控制每个数据成员的精确位置。如果使用 Explicit则每个成员必须使用FieldOffsetAttribute 来指示该字段在类型中的位置

CharSet     如果 CharSet 字段设置为 CharSet.Unicode,则所有字符串参数在传递到非托管实现之前都转换成 Unicode 字符 (LPWSTR)。如果该字段设置为 CharSet.Ansi,则字符串将转换成 ANSI 字符串 (LPSTR)。如果 CharSet 字段设置为 CharSet.Auto,则转换与平台相关。

Pack      控制类或结构的数据字段在内存中的对齐方式。

 

 1 /*  // LayoutKind.Explicit 示例 
 2 
 3 [StructLayout(LayoutKind.Explicit, Size=16, CharSet=CharSet.Ansi)]
 4 public class MySystemTime 
 5 {
 6    [FieldOffset(0)]public ushort wYear; 
 7    [FieldOffset(2)]public ushort wMonth;
 8    [FieldOffset(4)]public ushort wDayOfWeek; 
 9    [FieldOffset(6)]public ushort wDay; 
10    [FieldOffset(8)]public ushort wHour; 
11    [FieldOffset(10)]public ushort wMinute; 
12    [FieldOffset(12)]public ushort wSecond; 
13    [FieldOffset(14)]public ushort wMilliseconds; 
14 }*/

 

// 结构体转byte数组

 1 public static byte[] StructToBytes(object structObj,int size) 
 2 
 3 {
 4 
 5     byte[] bytes = new byte[size];
 6 
 7     IntPtr structPtr = Marshal.AllocHGlobal(size);
 8 
 9     //将结构体拷到分配好的内存空间
10 
11     Marshal.StructureToPtr(structObj, structPtr, false);
12 
13     //从内存空间拷贝到byte 数组
14 
15     Marshal.Copy(structPtr, bytes, 0, size);
16 
17     //释放内存空间 
18 
19     Marshal.FreeHGlobal(structPtr);
20 
21     return bytes;
22 
23 } 

 

//将Byte转换为结构体类型 

 1 public static object ByteToStruct(byte[] bytes, Type type) 
 2 
 3 {
 4 
 5     int size = Marshal.SizeOf(type);
 6 
 7     if (size > bytes.Length) 
 8 
 9     { 
10 
11         return null; 
12 
13     }
14 
15  
16 
17     //分配结构体内存空间 
18 
19     IntPtr structPtr = Marshal.AllocHGlobal(size); 
20 
21     //将byte数组拷贝到分配好的内存空间 
22 
23     Marshal.Copy(bytes, 0, structPtr, size); 
24 
25     //将内存空间转换为目标结构体 
26 
27     object obj = Marshal.PtrToStructure(structPtr, type); 
28 
29     //释放内存空间 
30 
31     Marshal.FreeHGlobal(structPtr);
32 
33  
34 
35     return obj; 
36 
37 }

 


// 实现将byte数组转换为结构体

1 byte[] eveArr = new byte[64];
2 
3do something for eveArr[];
4 
5 StructArgs actArgs = (StructArgs)ByteToStruct(eveArr, typeof(StructArgs)); 
6 
7 // byte数组转结构体的只需调用 StructToBytes(object structObj,int size);

 

posted @ 2015-12-22 16:26  sev  阅读(3303)  评论(0编辑  收藏  举报