C++ dll的創建和使用


在介紹Dll之前先了解下常見三種函數調用約定。

參考:https://www.cnblogs.com/yejianyong/p/7506465.html

我們使用的VS默認使用的函數調用約定是__cdel,而Windows API默認的調用約定是__stdcall。我們在使用一個dll的接口時,一定要確保你使用接口時的調用約定和接口定義時的調用約定一致。因為不同的調用約定,函數的棧內存釋放的方式不同。

 

然后我們再了解下extern C的作用,參考https://www.cnblogs.com/carsonzhu/p/5272271.html

如果我們使用C++進行程序開發,開發過程中使用到了C語言寫的庫函數,則我們就需要使用extern C 來修飾,來告訴編譯器,這部分代碼使用C語言語法進行編譯鏈接。

例如:

#ifdef __cplusplus

extern "C" {

#endif

#include "legacy_C_header.h"

#ifdef __cplusplus

}

#endif

這個就是它允許你在你的C ++代碼中使用這個C頭文件,因為宏“__cplusplus”將被定義。

 

下面我們開始學習C++Dll的創建和使用

C++創建的dll既可以給C++工程使用也可以給C#工程使用。

C++導出函數,在DLL中有一張導出表,記錄着需要導出的函數,這些函數可供外部程序調用,即這些函數都是該DLL的入口點(類似main函數)。不在導出表中的函數,為該DLL私有的函數,外部程序不能調用它們。

 

C++工程調用C++導出函數或者導出類

導出函數的幾個方法參考https://www.cnblogs.com/findumars/p/8660427.html

在函數聲明時,直接使用__declspec(dllexport)聲明函數

或者是直接使用def文件指定導出的函數

 

使用導出函數庫時,我們可以直接在VS上配置,指定庫目錄和動態庫對應的lib文件名,以及C/C++常規中的包含目錄,該目錄指定頭文件。

 

 

 

 

 

 

也可以直接在代碼中使用#pragma comment,具體語法可以參考https://blog.csdn.net/wfq_1985/article/details/7456591

使用如下:

#pragma comment(lib, "..\\CplusplusDll\\Debug\\CplusplusDll.lib")

 

當你不知道頭文件只知道你使用的函數類型時,則可以使用如下函數:

typedef int(*func)(int, int); 

HINSTANCE hInstance = LoadLibrary(L"..\\CplusplusDll\\Debug\\CplusplusDll.dll");

LPCSTR pc = "?GetMax@@YAHHH@Z";

func getmax = (func)GetProcAddress(hInstance, pc);

int max = getmax(a, b);

 

使用微軟VS提供的dumpbin –exports xxx.dll 可以查看你的函數名,同時你一定要確保你的調用約定和GetMax函數定義的一致。這里使用的是func的約定使用默認值一般是__cdel,函數GetMax定義的地方也是__cdel。如果是__stdcall則需要顯示聲明{typedef int(__stdcall*func)(int, int);}

注意,不建議直接使用這種方法對類的成員函數進行調用。

 

對於C++導出類,C++工程在調用時和導出函數一致,除了不能使用LoadLibrary函數進行動態加載外,VS配置和#progma預編譯指令都可以使用。

#include "../CplusplusDll/CMath.h"

#pragma comment(lib, "..\\CplusplusDll\\Debug\\CplusplusDll.lib")

CMath m;

int sum = m.add(5, 6, 7);

 

 

對於C#工程,如何調用C++導出函數呢?使用DllImport屬性,在System.Runtime.InteropServices命名空間下定義。參考https://www.cnblogs.com/xingboy/p/11158487.html,使用如下

 [DllImport(@"CplusplusDll.dll",CallingConvention = CallingConvention.Cdecl,EntryPoint = "?GetMax@@YAHHH@Z")]

public extern static int getMax(int a, int b);

int a = getMax(2, 3);

 

對於非托管的C++類,C#是無法直接使用,但是C#支持托管的C++代碼的使用。所以非托管的C++類,可以通過托管類包裝,進行導出,C++托管類使用的數據類型必須都是托管的,詳情可以以下鏈接:https://blog.csdn.net/weixin_34167819/article/details/91974250


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM