C#調(diào)用的C++庫
參考C#調(diào)用的C++庫的使用(三種方式)_Milu_Y-CSDN博客
c++庫函數(shù)庫包含公共方法,類臭猜、回調(diào)函數(shù),這三種在c#中調(diào)用的時候需要不同方式進行調(diào)用。
_declspec(dllexport)是用于Windows中的動態(tài)庫中哮塞,聲明導出函數(shù)纷闺、類算凿、對象等供外面調(diào)用,即將函數(shù)犁功、類等聲明為導出函數(shù)氓轰,供其它程序調(diào)用,作為動態(tài)庫的對外接口函數(shù)浸卦、類等署鸡。
__stdcall:Windows API默認的函數(shù)調(diào)用協(xié)議。
1 對于公共方法限嫌,因為涉及到的參數(shù)類型在c#和c++中可以通用靴庆,所以調(diào)用起來比較簡單。
比如一個C++類庫SampleCppWrapper.dll中的公共方法:
extern “C” __declspec(dllexport) int __stdcall Add(int n1, int n2);
__stdcall表示調(diào)用約定:參數(shù)都是從右向左通過堆棧傳遞萤皂, 函數(shù)調(diào)用在返回前要由被調(diào)用者清理堆棧撒穷。
這種情況使用的前提是c++庫中已經(jīng)完善了dll的導出,即將dll中的公共方法通過上述方式暴露出來裆熙,只有這樣才可以用下面的方式直接調(diào)用端礼。
在c#程序中調(diào)用該方法
[DllImport(“SampleCppWrapper.dll”)]
private static extern int Add(int n1, int n2);
下面是補充說明的在c++下生成dll動態(tài)鏈接庫的方法禽笑。
功能性Dll應該采用Win32控制臺的模板進行修改成Dll創(chuàng)建。例如add函數(shù)的使用在c++庫中要完成如下工作蛤奥。建立addfun.cpp以及相對應的頭文件addfun.h〖丫担現(xiàn)在我們開始編輯addfun.cpp文件了。如下所示:
// abc.cpp : 定義 DLL 應用程序的導出函數(shù)凡桥。
#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啊掏、 調(diào)用C++類庫中的類的方法
C#不能直接調(diào)用C++類庫中的類,類成員包含在類中無法直接進行調(diào)用衰猛,需要通過再做一個C++類庫把要調(diào)用的類成員方法暴露出來迟蜜,比如下面這個C++類:
//頭文件SampleCppClass.h
#pragmaonce
class __declspec(dllexport) SampleCppClass???? //類
{
public:SampleCppClass(void);
~SampleCppClass(void);
int Add(intn1,intn2);//成員函數(shù)
int Sub(intn1,intn2);//成員函數(shù)
};
SampleCppClass.cpp
#include "SampleCppClass.h"
SampleCppClass::SampleCppClass(void){}
SampleCppClass::~SampleCppClass(void){}
intSampleCppClass::Add(intn1,intn2){returnn1 + n2;}
intSampleCppClass::Sub(intn1,intn2){returnn1 - n2;}
我們要調(diào)用SampleCppClass中的Add和Sub兩個方法,所以我們再寫一個C++類庫啡省,通過公共方法間接調(diào)用類成員方法:
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#中娜睛,再調(diào)用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++類庫中的回調(diào)函數(shù)
用到的時候再進行補充卦睹。