C和C++中動態鏈接庫的創建和鏈接
1.創建DLL(動態鏈接庫)-C++方式
1.創建DLL(動態鏈接庫-C++方式)
1.在VS(以VS2017為例)中創建DLL動態鏈接庫。
解決方案名稱為:MyDLL
項目名稱為:Dll1
2.創建頭文件Dll1.h
輸入如下代碼:
#pragma once
#ifdef MY_DLL_EXP
#else
#define MY_DLL_EXP _declspec(dllimport)////當編譯時,頭文件不參加編譯,所以.cpp文件中先定義,后頭文件被包含進來,因此外部使用時,為dllexport,而在內部編譯時,則為dllimport
#endif
//創建一個常量
MY_DLL_EXP extern const double PI;
//創建一個測試用的函數
void MY_DLL_EXP Hello();
//創建一個測試用的類
class MY_DLL_EXP Calculate {
public:
double add(double a, double b);
double sub(double a, double b);
double mult(double a, double b);
double divd(double a, double b);
};
3.創建Dll1.cpp(如存在則不用創建)
輸入如下代碼:
#include "stdafx.h"
#include "Dll1.h"
//注意以上兩個頭文件的相對順序不能改變
#include <iostream>
#define MY_DLL_EXP _declspec(dllexport)
//導出常量
const double PI = 3.14;
//導出函數
void Hello() {
std::cout << "Hello World!" << std::endl;
}
//導出類中的函數
double Calculate::add(double a, double b) {
return a + b;
}
double Calculate::sub(double a, double b) {
return a - b;
}
double Calculate::mult(double a, double b) {
return a * b;
}
double Calculate::divd(double a, double b) {
if (b == 0)
return 0;
return a / b;
}
4.生成即可完成C++版動態鏈接庫的創建
注意:動態鏈接庫文件不能直接執行
2.鏈接DLL(動態鏈接庫-C++方式)
1.隱式鏈接
1.準備
Dll1.h(Dll1項目目錄中)
Dll1.lib(解決方案的Debug中)
Dll1.dll(結局方案的Debug中)
2.創建一個測試用隱式鏈接動態鏈接庫的項目
此處以空項目為例
項目名稱為:testDll1
此處為了方便,將Dll1.h,Dll1.lib,Dll1.dll放入到新建的項目目錄下。
3.右擊解決方案,選擇屬性。在通用屬性中的啟動項目中選擇當前選中內容,確認即可。
4.右擊要鏈接DLL的項目testDll1,選擇屬性,進行配置。
(1)配置屬性->VC++目錄->在"包含目錄"里添加頭文件Dll1.h所在的目錄
(2)配置屬性->VC++目錄->在"庫目錄"里添加頭文件Dll1.lib所在的目錄
(3)配置屬性->鏈接器->輸入->在"附加依賴項"里添加Dll1.lib(若有多個lib則以空格隔開)
4.將Dll1.dll文件放入到創建的項目的目錄下或是解決方案的Debug目錄下
5.創建testDll1.cpp
輸入如下測試代碼:
#include "Dll1.h"
#include <iostream>
//隱式調用DLL
using namespace std;
int main() {
cout << PI << endl;//測試輸出常量
Hello();//測試函數
//測試類
Calculate calc;
cout << "3 + 2 = " << calc.add(3, 2) << endl;
cout << "4 - 1 = " << calc.sub(4, 1) << endl;
cout << "3 * 2 = " << calc.mult(3, 2) << endl;
cout << "4 / 2 = " << calc.divd(4, 2) << endl;
cin.get();//暫停
}
輸出結果:
2.顯式鏈接
顯示鏈接可以在執行過程中隨時加載DLL文件,也可以隨時卸載DLL文件,這是隱式鏈接所無法作到的,所以顯式鏈接具有更好的靈活性,對于解釋性語言更為合適.
顯示鏈接主要是使用LoadLibrary()函數。此處只說明顯示鏈接DLL的導出函數的使用方法,導出類的使用比較復雜,將在我的其他文章中說明。
1.創建測試用空項目testDll2
2.將Dll1.dll放入到testDll2項目目錄下
3.創建testDll2.cpp
輸入如下代碼:
//顯示鏈接DLL-使用GetProcAddress獲取函數的名字會有所改變需要使用dumpbin.exe查詢
#include <Windows.h>//加載頭文件
#include <iostream>
using namespace std;
//設置全局變量hInst用于存儲dll句柄并加載動態鏈接庫
HINSTANCE hInst = nullptr;
//聲明函數指針
typedef void(*Hello)();
int main() {
//加載動態鏈接庫D111.dll
hInst = LoadLibrary("Dll1.dll");
if (hInst == nullptr) {
cout << "動態鏈接庫加載失敗!!!" << endl;
FreeLibrary(hInst);
cin.get();
return 0;
}
//加載導出函數,此處函數名有所不同,需要使用dumpbin.exe進行查詢
Hello hello = (Hello)GetProcAddress(hInst, "?Hello@@YAXXZ");
cout << "Hello()=";
hello();
cin.get();
//釋放動態鏈接庫
FreeLibrary(hInst);
return 0;
}
4.查詢函數名稱的方法
使用dumpbin.exe查詢
打開VS的自帶的本機工具命令提示
[圖片上傳失敗...(image-7efed-1547544495968)]
打開之后的界面:
進入Dll1.dll所在路徑
在控制臺中輸入dumpbin -exports Dll1.dll進行查詢
Hello函數的函數名為?Hello@@YAXXZ
5.生成并運行
運行結果
2.創建DLL(動態鏈接庫-C方式)
1.創建DLL(動態鏈接庫-C方式)
1.創建動態鏈接庫項目,名稱為Dll2
2.創建Dll2.h
輸入如下代碼
#pragma once
#ifdef MY_DLL_EXP
#else
#define MY_DLL_EXP _declspec(dllimport)////當編譯時,頭文件不參加編譯,所以.cpp文件中先定義,后頭文件被包含進來,因此外部使用時,為dllexport,而在內部編譯時,則為dllimport
#endif
//導出函數Add
extern "C" MY_DLL_EXP double Add(double a, double b);
3.創建Dll2.cpp(如果有則不需要創建)
輸入如下代碼:
#include "stdafx.h"
#include "Dll2.h"
//注意以上兩個頭文件的相對順序不能改變
#define MY_DLL_EXP _declspec(dllexport)
double Add(double a, double b) {
return a + b;
}
4.生成即可。
2.鏈接DLL(動態鏈接庫-C方式)
1.隱式鏈接
1.準備
Dll2.dll(解決方案Debug目錄下)
Dll2.lib(解決方案Debug目錄下)
2.創建測試項目testDll3
3.把Dll2.dll和Dll2.lib放入到testDll3項目目錄下
4.創建testDll3.cpp
輸入如下代碼:
//隱式調用
#include <iostream>
#pragma comment(lib,"Dll2.lib")
using namespace std;
//載入函數,此處起到頭文件的作用
extern "C" _declspec(dllimport) double Add(double a, double b);
int main() {
cout << "Add(3,4)=" << Add(3, 4) << endl;
cin.get();
return 0;
}
5.生成并運行
運行結果:
2.顯式鏈接
1.新建測試項目testDll4
2.把Dll2.dll放入新建的項目testDll4目錄中
3.新建testDll4.cpp
創建dll過程中使用C編譯器來編譯函數,這樣DLL文件中的函數名和原dll工程中的函數名就一致了。
墻裂推薦此種方式
輸入如下代碼:
//顯示鏈接DLL-C
#include <Windows.h>//加載頭文件
#include <iostream>
using namespace std;
//設置全局變量hInst用于存儲dll句柄并加載動態鏈接庫
HINSTANCE hInst = nullptr;
//聲明函數指針
typedef double(*Add)(double a,double b);
int main() {
//加載Dll2.dll
hInst = LoadLibrary("Dll2.dll");
if (hInst == nullptr) {
cout << "動態鏈接庫加載失敗!!!" << endl;
FreeLibrary(hInst);
cin.get();
return 0;
}
//加載函數
Add add = (Add)GetProcAddress(hInst, "Add");
cout << "Add(3,4)="<<add(3,4)<<endl;
cin.get();
FreeLibrary(hInst);
return 0;
}
4.生成并運行。
喜歡請關注一下呦~~~
簡書:http://www.lxweimin.com/u/27a54a63587e
博客園:https://www.cnblogs.com/xiangjinpeng/
CSDN:https://blog.csdn.net/qq_43210043
Github:https://github.com/XiangJinPeng