// 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
3 … do something for eveArr[];
4
5 StructArgs actArgs = (StructArgs)ByteToStruct(eveArr, typeof(StructArgs));
6
7 // byte数组转结构体的只需调用 StructToBytes(object structObj,int size);