邊界對齊

邊界對齊所屬現代詞,指的是指編輯C++時在使用結構體指針,進行C#和C++的互相調用。

邊界對齊是指編輯C++時在使用結構體指針,進行C#和C++的互相調用。邊界對齊是一個大問題,因為邊界對齊問題,結構體的成員並不是順序在記憶體一個挨著一個的排序。 而且在C++中可以使用#pragma pack(n)改變邊界對齊的方案,那C#的結構體怎么對應C++的結構體那?
第一:最普通的情況下,C++代碼沒有使用#pragma pack(n)改變邊界對齊,這裡C#可以使用兩種方法處理,LayoutKind.Explicit 和
LayoutKind.Sequential,建議使用後者,雖然前者是萬金油,不過使用起來太累又愛出錯。
C++:
1 struct Test1
2 {
3 int test1;
4 char test2;
5 __int64 test3;
6 short test4;
7 };
8 
9 Test1 * __stdcall GetTest1()
10 {
11 test1.test1 = 10;
12 test1.test2 = 11;
13 test1.test3 = 12;
14 test1.test4 = 13;
15 return &test1;
16 }
C#:(這裡有兩種方案,使用LayoutKind.Explicit 和LayoutKind.Sequential,注意一下)
1 [StructLayout(LayoutKind.Explicit)]
2 public struct Test
3 {
4 [FieldOffset(0)]
5 public int test1;
6 [FieldOffset(4)]
7 public char test2;
8 [FieldOffset(8)]
9 public Int64 test3;
10 [FieldOffset(16)]
11 public short test4;
12 }
13 
14 [StructLayout(LayoutKind.Sequential)]
15 public struct Test1
16 {
17 public int test1;
18 public char test2;
19 public Int64 test3;
20 public short test4;
21 }
22 
23 [DllImport("TestDll")]
24 public static extern IntPtr GetTest1();
25 
26 //#################################
27 IntPtr p = GetTest1();
28 Test test = (Test)Marshal.PtrToStructure(p, typeof(Test));
29 Console.WriteLine(test.test1 + test.test2 + test.test3 + test.test4);
30 
31 IntPtr p1 = GetTest1(); //Auto pack
32 Test1 test1 = (Test1)Marshal.PtrToStructure(p1, typeof(Test1));
33 Console.WriteLine(test1.test1 + test1.test2 + test1.test3 + test1.test4)

熱門詞條

聯絡我們