WEB开发网
开发学院软件开发C语言 c#编程指南(十二) 平台调用P-INVOKE完全掌握, 结构... 阅读

c#编程指南(十二) 平台调用P-INVOKE完全掌握, 结构体边界对齐和内存布局

 2010-09-30 22:46:08 来源:WEB开发网   
核心提示:在使用结构体指针,进行C#和C++的互相调用,c#编程指南(十二) 平台调用P-INVOKE完全掌握, 结构体边界对齐和内存布局,边界对齐是一个大问题,因为边界对齐问题,不过使用起来太累有爱出错,C++:1structTest12{3inttest1;4chartest2;5__int64test3;6shorttes

在使用结构体指针,进行C#和C++的互相调用。边界对齐是一个大问题,因为边界对齐问题,结构体的成员并不是顺序在内存一个挨着一个的排序。

而且在C++中可以使用#pragma pack(n)改变边界对齐的方案,那C#的结构体怎么对应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);

1 2  下一页

Tags:编程 指南 十二

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接