您的位置:首页 > 编程语言 > C#

c#编程指南(九) 平台调用P-INVOKE完全掌握,C#和C++互相调用

2010-08-24 17:02 495 查看
第一:C# 调用C++,使用P-INVOKE技术调用C++编写的动态链接库。而动态链接库导出的一般有两种调用协议,__stdcall和_cdecl。下面展示调用两种不同调用协议的方法:

C++:

int __stdcall Test1(int i)
{
return printf("The __stdcall invoke convesion:%d\n", i);
}

int _cdecl Test2(int i)
{
return printf("The _cdecl invoke convesion:%d\n", i);
}


c#:

[DllImport("TestDll", CallingConvention = CallingConvention.StdCall)]
public static extern int Test1(int i);

[DllImport("TestDll",CallingConvention= CallingConvention.Cdecl)]
public static extern int Test2(int i);

public void Run()
{
...
Test1(20);
Test2(30);
...
}


第二:C#调用C++代码,也可以间接的使用C++的函数指针。(强烈建议不要使用此方法)

c++:

typedef int ( __stdcall * FunctionPointerType1)(int i);
typedef int ( __cdecl * FunctionPointerType2)(int i);

int __stdcall Test1(int i)
{
return printf("The __stdcall invoke convesion:%d\n", i);
}

int _cdecl Test2(int i)
{
return printf("The _cdecl invoke convesion:%d\n", i);
}

FunctionPointerType1 GetFunctionPointer1(int i)
{
return Test1;
}

FunctionPointerType2 GetFunctionPointer2(int i)
{
return Test2;
}


C#:

[DllImport("TestDll")]
public static extern FunctionPointerType GetFunctionPointer1(int i);

[DllImport("TestDll")]
[return:MarshalAs(UnmanagedType.FunctionPtr)]
public static extern FunctionPointerType GetFunctionPointer2(int i);

public void Run()
{
...
FunctionPointerType func1 = GetFunctionPointer1(0);
FunctionPointerType func2 = GetFunctionPointer2(0);
//实验证明无论__stdcall和_cdecl函数指针C#都可以正常调用,
//具体内部不知道微软如何做的,高手指教了。
func1(40);
func2(50);
...
}


第三:C++调用C#函数,C#定义方法和方法的委托。传递委托给C++函数,.NET Framework会自动把委托转化成函数指针,对应的C++函数指针类型只能是__stdcall调用协议的,因为C#的方法默认编程成这个调用协议的,然后使用C++函数指针调用即可。

c#:

public delegate int FunctionPointerType(int i);

[DllImport("TestDll")]
public static extern int SetFunctionPointer(FunctionPointerType pointer);

FunctionPointerType test1 = delegate(int i) { Console.WriteLine("The C# Anonymous Method :" + i); return 0; };

public int CSharpTest1(int i)
{
Console.WriteLine("The C# member Method :" + i);
return 0;
}

public static int CSharpTest2(int i)
{
Console.WriteLine("The C# class Method :" + i);
return 0;
}

public void Run()
{
...
FunctionPointerType test2 = CSharpTest1;
FunctionPointerType test3 = CSharpTest2;
SetFunctionPointer(test1);
SetFunctionPointer(test2);
SetFunctionPointer(test3);
...
}


c++:

typedef int ( __stdcall * FunctionPointerType1)(int i);

int SetFunctionPointer(FunctionPointerType1 pointer)
{
return pointer(1);
}


微软很牛逼,基本上C#和C++互相调用完全没有问题,只要注意参数的Marshar和调用协议就可以了。

下载:代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: