当前位置: 首页 > news >正文

C++中显示与隐式加载dll的使用与区别

一、什么是 DLL?

DLL(Dynamic Link Library)是 Windows 下的动态链接库,包含可被多个程序共享的函数、资源或类。使用 DLL 可以实现代码复用、模块化设计和插件机制。

在 C++ 中,调用 DLL 中的函数有两种主要方式:

  1. 隐式链接(Implicit Linking)
  2. 显式链接(Explicit Linking)

二、隐式链接(Implicit Linking)

1. 原理

程序启动时自动加载 DLL,通过.lib导入库将 DLL 中的函数符号链接到可执行文件中。

2. 使用步骤

(1)准备三个文件:

  • MyDll.dll:动态库文件
  • MyDll.lib:导入库(由 DLL 生成)
  • MyDll.h:声明导出函数

(2)头文件示例(MyDll.h)

1

2

3

4

5

6

7

8

9

#ifdef __cplusplus

extern"C"{

#endif

__declspec(dllimport)intAdd(inta,intb);

#ifdef __cplusplus

}

#endif

注意:dllimport表示从 DLL 导入函数。

(3)链接.lib文件

在项目中添加.lib路径,并链接:

1

#pragma comment(lib, "MyDll.lib")

(4)直接调用函数

1

2

3

#include "MyDll.h"

intresult = Add(3, 4);// 直接像普通函数一样调用

3. 特点

优点缺点
使用简单,像调用本地函数启动时必须找到 DLL,否则程序无法启动
编译期检查函数签名不支持动态选择或延迟加载
性能略高(无需查表)难以实现插件系统或热更新

三、显式链接(Explicit Linking)

1. 原理

运行时通过LoadLibraryGetProcAddress手动加载 DLL 并获取函数地址。

2. 使用步骤

(1)不需要.lib文件,只需:

  • MyDll.dll
  • MyDll.h(知道函数原型)

(2)加载 DLL 并获取函数指针

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

#include <windows.h>

#include <iostream>

// 定义函数指针类型

typedefint(*AddFunc)(int,int);

intmain()

{

HMODULEhDll = LoadLibrary(_T("MyDll.dll"));// 加载 DLL

if(hDll == NULL) {

std::cout <<"无法加载 DLL!"<< std::endl;

return-1;

}

// 获取函数地址

AddFunc Add = (AddFunc)GetProcAddress(hDll,"Add");

if(!Add) {

std::cout <<"无法找到函数 Add!"<< std::endl;

FreeLibrary(hDll);

return-1;

}

// 调用函数

intresult = Add(3, 4);

std::cout <<"结果:"<< result << std::endl;

// 卸载 DLL

FreeLibrary(hDll);

return0;

}

3. 特点

优点缺点
运行时动态加载,灵活使用复杂,需手动管理函数指针
可判断 DLL 是否存在,提供降级方案无编译期检查,易出错(函数名拼错)
支持插件系统、热更新、按需加载性能稍低(需查表)
程序可容忍缺失 DLL需要正确处理FreeLibrary防止内存泄漏

四、核心区别对比表

对比项隐式链接显式链接
加载时机程序启动时自动加载运行时手动加载(LoadLibrary)
是否需要 .lib否(可选)
函数调用方式直接调用(如 Add(1,2))通过函数指针调用
启动依赖必须存在 DLL,否则无法启动可容忍缺失,运行时报错
灵活性高(可动态选择、卸载、替换)
适用场景核心功能、稳定依赖插件、可选模块、第三方组件
错误处理启动失败可在运行时提示用户
性能略高略低(需查找符号)
典型 API无(编译器自动处理)LoadLibrary, GetProcAddress, FreeLibrary

五、如何选择?

场景推荐方式
程序核心功能依赖的 DLL(如运行库)✅ 隐式链接
第三方 SDK、硬件驱动接口✅ 显式链接(容错更好)
实现插件系统(如 Photoshop 滤镜)✅ 显式链接
需要热更新或动态替换模块✅ 显式链接
小项目、简单调用、DLL 一定存在✅ 隐式链接更方便

六、最佳实践建议

  • 优先考虑显式链接用于第三方或可选模块,提升程序健壮性。
  • 使用 RAII 封装HMODULE,避免忘记FreeLibrary

1

2

3

4

5

6

7

8

classDllLoader {

public:

DllLoader(constTCHAR* name) { hDll = LoadLibrary(name); }

~DllLoader() {if(hDll) FreeLibrary(hDll); }

HMODULEget() {returnhDll; }

private:

HMODULEhDll = nullptr;

};

  • 导出 C 函数(用extern "C")避免 C++ 名称修饰问题。
  • 在发布程序时,确保 DLL 路径正确(当前目录、系统路径、应用程序目录等)。
http://www.jsqmd.com/news/887694/

相关文章:

  • 什么是吱吱OC|2026
  • Unity安卓构建72小时实战指南:从零到真机运行
  • 2026年全国瓷砖美缝剂主流品牌盘点与实测对比:屋顶防水材料、强力瓷砖背胶、强力瓷砖胶、新型防水材料、柔性瓷砖胶选择指南 - 优质品牌商家
  • SSH私钥权限600原理与Linux文件系统安全机制解析
  • 基于肠道菌群与机器学习的帕金森病早期诊断模型BDPM详解
  • Simulink仿真避坑指南:单相全桥逆变电路方波驱动相位设置(θ=30° vs 60°)对输出波形的影响深度对比
  • AssetStudio深度解析:Unity资源加载原理与故障排除实战
  • Unity安卓打包实战指南:从环境配置到APK生成全链路排错
  • 从测速到配置:一套完整的cFosSpeed网络加速保姆级教程(适用于小白)
  • 机器学习识别量子引力相变:从蒙特卡洛数据到相图自动化
  • 假设检验实战 | KS检验:从理论到Python代码的完整指南
  • Unity安卓构建实战指南:解决APK真机安装闪退与构建失败
  • AMD Ryzen平台VMware 16安装macOS Monterey避坑指南与性能调优
  • 2026年射洪市主流装饰公司盘点:射洪装饰公司/射洪装饰/射洪家装/射洪精装修/射洪整装/射洪装修公司/射洪装修/选择指南 - 优质品牌商家
  • 如何用ComfyUI-SUPIR实现专业级图像超分辨率:完整实战指南
  • Unity Instantiate卡顿根因与四层优化实战指南
  • Unity微信小游戏4MB包体优化实战:WebP分包Addressables三阶瘦身
  • 告别硬编码!Spring Cloud Gateway + Sentinel 1.8.6 动态流控规则配置实战
  • 如何快速掌握Redis可视化工具:5分钟上手完全指南
  • Unity Android SDK消失根因与五步闭环解决方案
  • Unity超休闲游戏上线模板:Google Play合规与性能预埋实践
  • 机器学习赋能6G近场通信:从信道估计到波束赋形的智能革命
  • 基于XGBoost与SHAP的分子气味预测:从特征工程到可解释性分析
  • 机器学习结合基因无关通路映射:从临床数据挖掘新药靶点
  • 基于XGBoost与公开数据的ISP对等伙伴智能推荐模型实践
  • 无需sdk,使用curl命令直接测试taotoken的openai兼容api接口
  • 集成学习与可解释AI在无人机网络入侵检测中的实践
  • 肺癌预后预测:Cox模型与随机生存森林的性能对比与临床实践
  • 机器学习算法对比:慢性肾病预测中逻辑回归与随机森林表现最佳
  • VRM模型Blender转Unity无损FBX导出全流程