C++中顯示與隱式加載dll的使用與區(qū)別
一、什么是 DLL?
DLL(Dynamic Link Library) 是 Windows 下的動態(tài)鏈接庫,包含可被多個程序共享的函數(shù)、資源或類。使用 DLL 可以實(shí)現(xiàn)代碼復(fù)用、模塊化設(shè)計和插件機(jī)制。
在 C++ 中,調(diào)用 DLL 中的函數(shù)有兩種主要方式:
- 隱式鏈接(Implicit Linking)
- 顯式鏈接(Explicit Linking)
二、隱式鏈接(Implicit Linking)
1. 原理
程序啟動時自動加載 DLL,通過 .lib 導(dǎo)入庫將 DLL 中的函數(shù)符號鏈接到可執(zhí)行文件中。
2. 使用步驟
(1)準(zhǔn)備三個文件:
MyDll.dll:動態(tài)庫文件MyDll.lib:導(dǎo)入庫(由 DLL 生成)MyDll.h:聲明導(dǎo)出函數(shù)
(2)頭文件示例(MyDll.h)
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllimport) int Add(int a, int b);
#ifdef __cplusplus
}
#endif注意:dllimport 表示從 DLL 導(dǎo)入函數(shù)。
(3)鏈接 .lib 文件
在項(xiàng)目中添加 .lib 路徑,并鏈接:
#pragma comment(lib, "MyDll.lib")
(4)直接調(diào)用函數(shù)
#include "MyDll.h" int result = Add(3, 4); // 直接像普通函數(shù)一樣調(diào)用
3. 特點(diǎn)
| 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|
| 使用簡單,像調(diào)用本地函數(shù) | 啟動時必須找到 DLL,否則程序無法啟動 |
| 編譯期檢查函數(shù)簽名 | 不支持動態(tài)選擇或延遲加載 |
| 性能略高(無需查表) | 難以實(shí)現(xiàn)插件系統(tǒng)或熱更新 |
三、顯式鏈接(Explicit Linking)
1. 原理
運(yùn)行時通過 LoadLibrary 和 GetProcAddress 手動加載 DLL 并獲取函數(shù)地址。
2. 使用步驟
(1)不需要 .lib 文件,只需:
MyDll.dllMyDll.h(知道函數(shù)原型)
(2)加載 DLL 并獲取函數(shù)指針
#include <windows.h>
#include <iostream>
// 定義函數(shù)指針類型
typedef int (*AddFunc)(int, int);
int main()
{
HMODULE hDll = LoadLibrary(_T("MyDll.dll")); // 加載 DLL
if (hDll == NULL) {
std::cout << "無法加載 DLL!" << std::endl;
return -1;
}
// 獲取函數(shù)地址
AddFunc Add = (AddFunc)GetProcAddress(hDll, "Add");
if (!Add) {
std::cout << "無法找到函數(shù) Add!" << std::endl;
FreeLibrary(hDll);
return -1;
}
// 調(diào)用函數(shù)
int result = Add(3, 4);
std::cout << "結(jié)果:" << result << std::endl;
// 卸載 DLL
FreeLibrary(hDll);
return 0;
}3. 特點(diǎn)
| 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|
| 運(yùn)行時動態(tài)加載,靈活 | 使用復(fù)雜,需手動管理函數(shù)指針 |
| 可判斷 DLL 是否存在,提供降級方案 | 無編譯期檢查,易出錯(函數(shù)名拼錯) |
| 支持插件系統(tǒng)、熱更新、按需加載 | 性能稍低(需查表) |
| 程序可容忍缺失 DLL | 需要正確處理 FreeLibrary 防止內(nèi)存泄漏 |
四、核心區(qū)別對比表
| 對比項(xiàng) | 隱式鏈接 | 顯式鏈接 |
|---|---|---|
| 加載時機(jī) | 程序啟動時自動加載 | 運(yùn)行時手動加載(LoadLibrary) |
| 是否需要 .lib | 是 | 否(可選) |
| 函數(shù)調(diào)用方式 | 直接調(diào)用(如 Add(1,2)) | 通過函數(shù)指針調(diào)用 |
| 啟動依賴 | 必須存在 DLL,否則無法啟動 | 可容忍缺失,運(yùn)行時報錯 |
| 靈活性 | 低 | 高(可動態(tài)選擇、卸載、替換) |
| 適用場景 | 核心功能、穩(wěn)定依賴 | 插件、可選模塊、第三方組件 |
| 錯誤處理 | 啟動失敗 | 可在運(yùn)行時提示用戶 |
| 性能 | 略高 | 略低(需查找符號) |
| 典型 API | 無(編譯器自動處理) | LoadLibrary, GetProcAddress, FreeLibrary |
五、如何選擇?
| 場景 | 推薦方式 |
|---|---|
| 程序核心功能依賴的 DLL(如運(yùn)行庫) | ? 隱式鏈接 |
| 第三方 SDK、硬件驅(qū)動接口 | ? 顯式鏈接(容錯更好) |
| 實(shí)現(xiàn)插件系統(tǒng)(如 Photoshop 濾鏡) | ? 顯式鏈接 |
| 需要熱更新或動態(tài)替換模塊 | ? 顯式鏈接 |
| 小項(xiàng)目、簡單調(diào)用、DLL 一定存在 | ? 隱式鏈接更方便 |
六、最佳實(shí)踐建議
- 優(yōu)先考慮顯式鏈接 用于第三方或可選模塊,提升程序健壯性。
- 使用 RAII 封裝
HMODULE,避免忘記FreeLibrary:
class DllLoader {
public:
DllLoader(const TCHAR* name) { hDll = LoadLibrary(name); }
~DllLoader() { if (hDll) FreeLibrary(hDll); }
HMODULE get() { return hDll; }
private:
HMODULE hDll = nullptr;
};- 導(dǎo)出 C 函數(shù)(用
extern "C")避免 C++ 名稱修飾問題。 - 在發(fā)布程序時,確保 DLL 路徑正確(當(dāng)前目錄、系統(tǒng)路徑、應(yīng)用程序目錄等)。
七、補(bǔ)充:如何導(dǎo)出 DLL 函數(shù)?
// MyDll.cpp
extern "C" __declspec(dllexport) int Add(int a, int b)
{
return a + b;
}extern "C" 防止 C++ 編譯器名稱修飾,便于 GetProcAddress 查找。
總結(jié)
| 方式 | 何時用 | 關(guān)鍵詞 |
|---|---|---|
| 隱式鏈接 | 簡單、固定依賴 | .lib、啟動加載、直接調(diào)用 |
| 顯式鏈接 | 靈活、容錯、插件 | LoadLibrary、GetProcAddress、運(yùn)行時加載 |
?? 一句話總結(jié):
- 要簡單直接 → 用 隱式鏈接
- 要靈活可控 → 用 顯式鏈接
顯示聲明與隱式聲明的使用與區(qū)別
到此這篇關(guān)于C++中顯示與隱式加載dll的使用與區(qū)別的文章就介紹到這了,更多相關(guān)C++ 顯示與隱式加載dll內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++與QML進(jìn)行數(shù)據(jù)交互實(shí)現(xiàn)方式介紹
迫于無奈開始寫android的程序,以前使用QWidget的方式試過,雖然界面可以實(shí)現(xiàn),但是最后調(diào)用攝像頭時,未能成功,再沒有繼續(xù)。這幾天開始使用qml進(jìn)行嘗試,在使用的過程中,其中的一個難點(diǎn),就是在qml與c++中數(shù)據(jù)的交互2022-09-09
C語言實(shí)現(xiàn)飛機(jī)訂票系統(tǒng)的完整代碼
為了免去在窗口排隊買票的麻煩,飛機(jī)訂票系統(tǒng)應(yīng)運(yùn)而生,下面這篇文章主要給大家介紹了關(guān)于C語言實(shí)現(xiàn)飛機(jī)訂票系統(tǒng)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
Visual Studio 2022 上使用ffmpeg的詳細(xì)步驟
文章介紹了在開發(fā)項(xiàng)目中配置FFmpeg庫的步驟,添加包含目錄、庫目錄、依賴項(xiàng)及動態(tài)庫路徑,確保編譯器和鏈接器正確識別FFmpeg資源,最后通過測試驗(yàn)證配置有效性,感興趣的朋友一起看看吧2025-07-07
深入分析C語言分解質(zhì)因數(shù)的實(shí)現(xiàn)方法
這篇文章主要介紹了深入分析C語言分解質(zhì)因數(shù)的實(shí)現(xiàn)方法,作者結(jié)合了ACM題目作為相關(guān)拓展,需要的朋友可以參考下2015-08-08
c語言標(biāo)準(zhǔn)庫中字符轉(zhuǎn)換函數(shù)和數(shù)字轉(zhuǎn)換函數(shù)
這篇文章主要介紹了c標(biāo)準(zhǔn)庫中字符轉(zhuǎn)換函數(shù)和數(shù)字轉(zhuǎn)換函數(shù),需要的朋友可以參考下2014-04-04
C++利用std::forward_list查找插入數(shù)據(jù)方法示例
這篇文章主要給大家介紹了關(guān)于C++利用std::forward_list查找插入數(shù)據(jù)的相關(guān)資料,文中先對std::forward_list進(jìn)行了詳細(xì)的介紹,而后通過示例代碼給大家介紹了查找的方法,需要的朋友可以參考借鑒,下面話不多說了,來一起看看吧。2017-08-08

