C#调用的C++库
参考C#调用的C++库的使用(三种方式)_Milu_Y-CSDN博客
c++库函数库包含公共方法,类、回调函数,这三种在c#中调用的时候需要不同方式进行调用。
_declspec(dllexport)是用于Windows中的动态库中,声明导出函数、类、对象等供外面调用,即将函数、类等声明为导出函数,供其它程序调用,作为动态库的对外接口函数、类等。
__stdcall:Windows API默认的函数调用协议。
1 对于公共方法,因为涉及到的参数类型在c#和c++中可以通用,所以调用起来比较简单。
比如一个C++类库SampleCppWrapper.dll中的公共方法:
extern “C” __declspec(dllexport) int __stdcall Add(int n1, int n2);
__stdcall表示调用约定:参数都是从右向左通过堆栈传递, 函数调用在返回前要由被调用者清理堆栈。
这种情况使用的前提是c++库中已经完善了dll的导出,即将dll中的公共方法通过上述方式暴露出来,只有这样才可以用下面的方式直接调用。
在c#程序中调用该方法
[DllImport(“SampleCppWrapper.dll”)]
private static extern int Add(int n1, int n2);
下面是补充说明的在c++下生成dll动态链接库的方法。
功能性Dll应该采用Win32控制台的模板进行修改成Dll创建。例如add函数的使用在c++库中要完成如下工作。建立addfun.cpp以及相对应的头文件addfun.h。现在我们开始编辑addfun.cpp文件了。如下所示:
// abc.cpp : 定义 DLL 应用程序的导出函数。
#include "stdafx.h"
#include "addfun.h"
int add(int a,int b)
{ return a+b;}
在对应的头文件addfun.h中如下所示:
#include "stdafx.h"
extern "C"
{
_declspec(dllexport) int add(int a,int b);
typedef int (* ApiAdd)(int,int);
}
按照上面的格式我们编译就能生成我们想要的dll的api。
通过以上4步,我们可以在工程的Debug目录下找到addfun.dll和addfun.lib。
2、 调用C++类库中的类的方法
C#不能直接调用C++类库中的类,类成员包含在类中无法直接进行调用,需要通过再做一个C++类库把要调用的类成员方法暴露出来,比如下面这个C++类:
//头文件SampleCppClass.h
#pragmaonce
class __declspec(dllexport) SampleCppClass //类
{
public:SampleCppClass(void);
~SampleCppClass(void);
int Add(intn1,intn2);//成员函数
int Sub(intn1,intn2);//成员函数
};
SampleCppClass.cpp
#include "SampleCppClass.h"
SampleCppClass::SampleCppClass(void){}
SampleCppClass::~SampleCppClass(void){}
intSampleCppClass::Add(intn1,intn2){returnn1 + n2;}
intSampleCppClass::Sub(intn1,intn2){returnn1 - n2;}
我们要调用SampleCppClass中的Add和Sub两个方法,所以我们再写一个C++类库,通过公共方法间接调用类成员方法:
SampleCppWrapper.h
#pragma once
#include "..\SampleCppClass\SampleCppClass.h"
namespace SampleCppWrapper
{
extern"C" __declspec(dllexport) int__stdcall Add(intn1,intn2);
extern"C" __declspec(dllexport) int__stdcall Sub(intn1,intn2);
}
SampleCppWrapper.cpp
#include "SampleCppWrapper.h"
namespaceSampleCppWrapper
{
SampleCppClass* g_pObj =newSampleCppClass();
int __stdcall Add(intn1,intn2)
{
return g_pObj->Add(n1, n2);
}
int __stdcall Sub(intn1,intn2)
{
return g_pObj->Sub(n1, n2);
}
}
在C#中,再调用SampleCppWrapper.dll中的公共方法:
[DllImport(“SampleCppWrapper.dll”)]
private static extern int Add(int n1, int n2);
[DllImport(“SampleCppWrapper.dll”)]
private static extern int Sub(int n1, int n2);
3、 使用C++类库中的回调函数
用到的时候再进行补充。