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

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

 2010-09-30 22:46:08 来源:WEB开发网   
核心提示: 第二:特殊的情况下,C++代码使用#pragma pack(n)改变了边界对齐,c#编程指南(十二) 平台调用P-INVOKE完全掌握, 结构体边界对齐和内存布局(2),这里要使用C#要使用 [StructLayout(LayoutKind.Sequential, Pack = N)] 对齐,

第二:特殊的情况下,C++代码使用#pragma pack(n)改变了边界对齐。这里要使用C#要使用   [StructLayout(LayoutKind.Sequential, Pack = N)] 对齐,否则出错。

C++:

 1 #pragma pack(1)
 2  struct Test2
 3 {
 4   int test1;
 5   char test2;
 6   __int64 test3;
 7   short test4;
 8 };
 9  #pragma pack()
10 
11  #pragma pack(2)
12  struct Test3
13 {
14   int test1;
15   char test2;
16   __int64 test3;
17   short test4;
18 };
19  #pragma pack()
20 
21 
22  #pragma pack(4)
23  struct Test4
24 {
25   int test1;
26   char test2;
27   __int64 test3;
28   short test4;
29 };
30  #pragma pack()

C#:

 1   [StructLayout(LayoutKind.Sequential, Pack = 1)]
 2   struct Test2
 3   {
 4     public int test1;
 5     public char test2;
 6     public Int64 test3;
 7     public short test4;
 8   }
 9 
10   [StructLayout(LayoutKind.Sequential, Pack = 2)]
11   struct Test3
12   {
13     public int test1;
14     public char test2;
15     public Int64 test3;
16     public short test4;
17   }
18 
19   [StructLayout(LayoutKind.Sequential, Pack = 4)]
20   struct Test4
21   {
22     public int test1;
23     public char test2;
24     public Int64 test3;
25     public short test4;
26   }
27 
28 
29     [DllImport("TestDll")]
30     public static extern IntPtr GetTest2();
31 
32     [DllImport("TestDll")]
33     public static extern IntPtr GetTest3();
34 
35     [DllImport("TestDll")]
36     public static extern IntPtr GetTest4();
37 
38       //#################################
39        IntPtr p2 = GetTest2(); //pack 1
40        Test2 test2 = (Test2)Marshal.PtrToStructure(p2, typeof(Test2));
41 
42       IntPtr p3 = GetTest3(); //pack 2
43        Test3 test3 = (Test3)Marshal.PtrToStructure(p3, typeof(Test3));
44 
45       IntPtr p4 = GetTest4(); //pack4
46        Test4 test4 = (Test4)Marshal.PtrToStructure(p4, typeof(Test4));
47 
48       Console.WriteLine(test2.test1 + test2.test2 + test2.test3 + test2.test4);
49       Console.WriteLine(test3.test1 + test3.test2 + test3.test3 + test3.test4);
50       Console.WriteLine(test4.test1 + test4.test2 + test4.test3 + test4.test4);

最后总结一下,LayoutKind有3个枚举值。LayoutKind.Auto ,LayoutKind.Explicit 和LayoutKind.Sequential.LayoutKind.Auto或者为使用LayoutKind属性的结构体,

进行P-INVOKE调用会抛出异常,改类型不允许进行P-INVOKE调用,LayoutKind.Sequential在内存中顺序布局,一般情况(上面两种)推荐用这个。LayoutKind.Explicit

只推荐特殊情况使用,因为他会明确指定成员的内存offset,很强大也很繁琐。

上一页  1 2 

Tags:编程 指南 十二

编辑录入:爽爽 [复制链接] [打 印]
[]
  • 好
  • 好的评价 如果觉得好,就请您
      0%(0)
  • 差
  • 差的评价 如果觉得差,就请您
      0%(0)
赞助商链接