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

c#编程指南(十三) 平台调用P-INVOKE完全掌握, 结构体和结构体指针

 2010-09-30 22:46:05 来源:WEB开发网   
核心提示: 第二,C++导出函数和C# P-INVOKE函数的对应,c#编程指南(十三) 平台调用P-INVOKE完全掌握, 结构体和结构体指针(2),C++:1staticTest_test;2voidSetTest(Testtest)3{4_test=test;5PrintTest();6}78void

第二。C++导出函数和C# P-INVOKE函数的对应。

C++:

 1 static Test _test;
 2  void SetTest(Test test)
 3 {
 4   _test = test;
 5   PrintTest();
 6 }
 7 
 8  void SetTestPointer(Test * lptest)
 9 {
10   _test = * lptest;
11   PrintTest();
12 }
13 
14 Test GetTest()
15 {
16   return _test;  
17 }
18 
19 Test * GetTestPointer()
20 {
21   return &_test;
22 }

C#:   注意结构体作为返回值的P-INVOKE声明是不是很奇怪。不过运行很正常。下一篇结合反汇编说。

 1     [DllImport("TestDll")]
 2     public static extern void SetTest(Test test);
 3 
 4     [DllImport("TestDll")]
 5     public static extern void SetTestPointer(IntPtr lptest);
 6 
 7     [DllImport("TestDll")]
 8     public static extern void GetTest(IntPtr lptest); //注意声明。
 9  
10     [DllImport("TestDll")]
11     public static extern IntPtr GetTestPointer();

第三:看下C#如何调用,这里用到了Marshal.AllocHGlobal 方法,和Alloc功能基本一样,会造成内存泄露,使用完了记住使用Marshal.FreeHGlobal函数释放申请的内存。

 1     private Test _test = new Test();
 2 
 3     public void Run()
 4     {
 5       InitTest();
 6       //#########################
 7        SetTest(_test);
 8       Console.WriteLine("-------------------------------------------------------------\n");
 9       //#########################  
10        _test._base.BaseInt = 9999;
11   //Marshal.AllocHGlobal 和WIN32 API, Alloc功能基本一样,
12   //这个方法不要多用,可能造成内存泄露。
13   //记住使用Marshal.FreeHGlobal函数释放申请的内存
14        IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Test)));
15       Marshal.StructureToPtr(_test,p,false);
16       SetTestPointer(p);
17       Console.WriteLine("-------------------------------------------------------------\n");
18       //#########################
19        IntPtr pp = GetTestPointer();
20       Test temp = (Test)Marshal.PtrToStructure(pp, typeof(Test));
21       PrintTest(temp);
22       Console.WriteLine("-------------------------------------------------------------\n");
23 
24       //#########################
25        IntPtr pp2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Test)));
26       GetTest(pp2);
27       Test temp2 = (Test)Marshal.PtrToStructure(pp2, typeof(Test));
28       PrintTest(temp2);
29       
30     }

总结一下:Marshal.StructureToPtr从托管类复制数据到未托管的内存中,Marshal.PtrToStructure恰好相反。Marshal.AllocHGlobal申请非托管内存,Marshal.FreeHGlobal函数释放非托管内存。使用 Marshal.Read系列读写指针,使用Marshal.ReadIntPtr来读写二级指针。

上一页  1 2 

Tags:编程 指南 十三

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