平台调用 4000 P-INVOKE完全掌握,C#和C++互相调用
2014-09-18 15:43
519 查看
第一:C# 调用C++,使用P-INVOKE技术调用C++编写的动态链接库。而动态链接库导出的一般有两种调用协议,__stdcall和_cdecl。下面展示调用两种不同调用协议的方法:
C++:
1 int __stdcall Test1(int i)
2 {
3 return printf("The __stdcall invoke convesion:%d\n", i);
4 }
5
6 int _cdecl Test2(int i)
7 {
8 return printf("The _cdecl invoke convesion:%d\n", i);
9 }
c#:
1 [DllImport("TestDll", CallingConvention = CallingConvention.StdCall)]
2 public static extern int Test1(int i);
3
4 [DllImport("TestDll",CallingConvention= CallingConvention.Cdecl)]
5 public static extern int Test2(int i);
6
7 public void Run()
8 {
9 ...
10 Test1(20);
11 Test2(30);
12 ...
13 }
第二:C#调用C++代码,也可以间接的使用C++的函数指针。(强烈建议不要使用此方法)
c++:
1 typedef int ( __stdcall * FunctionPointerType1)(int i);
2 typedef int ( __cdecl * FunctionPointerType2)(int i);
3
4 int __stdcall Test1(int i)
5 {
6 return printf("The __stdcall invoke convesion:%d\n", i);
7 }
8
9 int _cdecl Test2(int i)
10 {
11 return printf("The _cdecl invoke convesion:%d\n", i);
12 }
13
14 FunctionPointerType1 GetFunctionPointer1(int i)
15 {
16 return Test1;
17 }
18
19 FunctionPointerType2 GetFunctionPointer2(int i)
20 {
21 return Test2;
22 }
C#:
1 [DllImport("TestDll")]
2 public static extern FunctionPointerType GetFunctionPointer1(int i);
3
4 [DllImport("TestDll")]
5 [return:MarshalAs(UnmanagedType.FunctionPtr)]
6 public static extern FunctionPointerType GetFunctionPointer2(int i);
7
8 public void Run()
9 {
10 ...
11 FunctionPointerType func1 = GetFunctionPointer1(0);
12 FunctionPointerType func2 = GetFunctionPointer2(0);
13 //实验证明无论__stdcall和_cdecl函数指针C#都可以正常调用,
14 //具体内部不知道微软如何做的,高手指教了。
15 func1(40);
16 func2(50);
17 ...
18 }
第三:C++调用C#函数,C#定义方法和方法的委托。传递委托给C++函数,.NET Framework会自动把委托转化成函数指针,对应的C++函数指针类型只能是__stdcall调用协议的,因为C#的方法默认编程成这个调用协议的,然后使用C++函数指针调用即可。
c#:
1 public delegate int FunctionPointerType(int i);
2
3 [DllImport("TestDll")]
4 public static extern int SetFunctionPointer(FunctionPointerType pointer);
5
6 FunctionPointerType test1 = delegate(int i) { Console.WriteLine("The C# Anonymous Method :" + i); return 0; };
7
8 public int CSharpTest1(int i)
9 {
10 Console.WriteLine("The C# member Method :" + i);
11 return 0;
12 }
13
14 public static int CSharpTest2(int i)
15 {
16 Console.WriteLine("The C# class Method :" + i);
17 return 0;
18 }
19
20 public void Run()
21 {
22 ...
23 FunctionPointerType test2 = CSharpTest1;
24 FunctionPointerType test3 = CSharpTest2;
25 SetFunctionPointer(test1);
26 SetFunctionPointer(test2);
27 SetFunctionPointer(test3);
28 ...
29 }
c++:
1 typedef int ( __stdcall * FunctionPointerType1)(int i);
2
3 int SetFunctionPointer(FunctionPointerType1 pointer)
4 {
5 return pointer(1);
6 }
微软很牛逼,基本上C#和C++互相调用完全没有问题,只要注意参数的Marshar和调用协议就可以了。
C++:
1 int __stdcall Test1(int i)
2 {
3 return printf("The __stdcall invoke convesion:%d\n", i);
4 }
5
6 int _cdecl Test2(int i)
7 {
8 return printf("The _cdecl invoke convesion:%d\n", i);
9 }
c#:
1 [DllImport("TestDll", CallingConvention = CallingConvention.StdCall)]
2 public static extern int Test1(int i);
3
4 [DllImport("TestDll",CallingConvention= CallingConvention.Cdecl)]
5 public static extern int Test2(int i);
6
7 public void Run()
8 {
9 ...
10 Test1(20);
11 Test2(30);
12 ...
13 }
第二:C#调用C++代码,也可以间接的使用C++的函数指针。(强烈建议不要使用此方法)
c++:
1 typedef int ( __stdcall * FunctionPointerType1)(int i);
2 typedef int ( __cdecl * FunctionPointerType2)(int i);
3
4 int __stdcall Test1(int i)
5 {
6 return printf("The __stdcall invoke convesion:%d\n", i);
7 }
8
9 int _cdecl Test2(int i)
10 {
11 return printf("The _cdecl invoke convesion:%d\n", i);
12 }
13
14 FunctionPointerType1 GetFunctionPointer1(int i)
15 {
16 return Test1;
17 }
18
19 FunctionPointerType2 GetFunctionPointer2(int i)
20 {
21 return Test2;
22 }
C#:
1 [DllImport("TestDll")]
2 public static extern FunctionPointerType GetFunctionPointer1(int i);
3
4 [DllImport("TestDll")]
5 [return:MarshalAs(UnmanagedType.FunctionPtr)]
6 public static extern FunctionPointerType GetFunctionPointer2(int i);
7
8 public void Run()
9 {
10 ...
11 FunctionPointerType func1 = GetFunctionPointer1(0);
12 FunctionPointerType func2 = GetFunctionPointer2(0);
13 //实验证明无论__stdcall和_cdecl函数指针C#都可以正常调用,
14 //具体内部不知道微软如何做的,高手指教了。
15 func1(40);
16 func2(50);
17 ...
18 }
第三:C++调用C#函数,C#定义方法和方法的委托。传递委托给C++函数,.NET Framework会自动把委托转化成函数指针,对应的C++函数指针类型只能是__stdcall调用协议的,因为C#的方法默认编程成这个调用协议的,然后使用C++函数指针调用即可。
c#:
1 public delegate int FunctionPointerType(int i);
2
3 [DllImport("TestDll")]
4 public static extern int SetFunctionPointer(FunctionPointerType pointer);
5
6 FunctionPointerType test1 = delegate(int i) { Console.WriteLine("The C# Anonymous Method :" + i); return 0; };
7
8 public int CSharpTest1(int i)
9 {
10 Console.WriteLine("The C# member Method :" + i);
11 return 0;
12 }
13
14 public static int CSharpTest2(int i)
15 {
16 Console.WriteLine("The C# class Method :" + i);
17 return 0;
18 }
19
20 public void Run()
21 {
22 ...
23 FunctionPointerType test2 = CSharpTest1;
24 FunctionPointerType test3 = CSharpTest2;
25 SetFunctionPointer(test1);
26 SetFunctionPointer(test2);
27 SetFunctionPointer(test3);
28 ...
29 }
c++:
1 typedef int ( __stdcall * FunctionPointerType1)(int i);
2
3 int SetFunctionPointer(FunctionPointerType1 pointer)
4 {
5 return pointer(1);
6 }
微软很牛逼,基本上C#和C++互相调用完全没有问题,只要注意参数的Marshar和调用协议就可以了。
相关文章推荐
- c#编程指南(九) 平台调用P-INVOKE完全掌握,C#和C++互相调用
- c#编程指南——平台调用P-INVOKE完全掌握,C#和C++互相调用
- c#编程指南(十) 平台调用P-INVOKE完全掌握, 字符串和指针
- c#编程指南(十四) 平台调用P-INVOKE完全掌握, 反汇编细解结构体作为返回值
- 平台调用P-INVOKE完全掌握, 反汇编细解结构体作为返回值
- C#调用C++ 平台调用P/Invoke 结构体--输入输出参数、返回值、返出值、结构体数组作为参数【五】
- c#编程指南(十) 平台调用P-INVOKE完全掌握, 字符串和指针
- C#调用C++ 平台调用P/Invoke 调用约定【一】
- Android 平台C# 与C++之间的互相调用方法
- c#编程指南(十一) 平台调用P-INVOKE完全掌握, 指针大全
- 平台调用P-INVOKE完全掌握, 结构体和结构体指针
- c#编程指南(十) 平台调用P-INVOKE完全掌握, 字符串和指针
- C#调用C++ 平台调用P/Invoke 结构体--内存对齐方式、union封装【七】
- c#编程指南(十二) 平台调用P-INVOKE完全掌握, 结构体边界对齐和内存布局
- 平台调用P-INVOKE完全掌握, 结构体边界对齐和内存布局
- C#调用C++ 平台调用P/Invoke 错误码LastError【四】
- C#调用C++ 平台调用P/Invoke 结构体--含有内置数据类型的一维、二维数组、字符串指针【六】
- C#调用C++ 平台调用P/Invoke 函数指针/回调函数【二】
- c#编程指南(十五) 平台调用P-INVOKE完全掌握(完结篇),自定义Mashaler
- c#编程指南(十三) 平台调用P-INVOKE完全掌握, 结构体和结构体指针