一、什么是 DLLDLLDynamic Link Library是 Windows 下的动态链接库包含可被多个程序共享的函数、资源或类。使用 DLL 可以实现代码复用、模块化设计和插件机制。在 C 中调用 DLL 中的函数有两种主要方式隐式链接Implicit Linking显式链接Explicit Linking二、隐式链接Implicit Linking1. 原理程序启动时自动加载 DLL通过.lib导入库将 DLL 中的函数符号链接到可执行文件中。2. 使用步骤1准备三个文件MyDll.dll动态库文件MyDll.lib导入库由 DLL 生成MyDll.h声明导出函数2头文件示例MyDll.h123456789#ifdef __cplusplusexternC{#endif__declspec(dllimport)intAdd(inta,intb);#ifdef __cplusplus}#endif注意dllimport表示从 DLL 导入函数。3链接.lib文件在项目中添加.lib路径并链接1#pragma comment(lib, MyDll.lib)4直接调用函数123#include MyDll.hintresult Add(3, 4);// 直接像普通函数一样调用3. 特点优点缺点使用简单像调用本地函数启动时必须找到 DLL否则程序无法启动编译期检查函数签名不支持动态选择或延迟加载性能略高无需查表难以实现插件系统或热更新三、显式链接Explicit Linking1. 原理运行时通过LoadLibrary和GetProcAddress手动加载 DLL 并获取函数地址。2. 使用步骤1不需要.lib文件只需MyDll.dllMyDll.h知道函数原型2加载 DLL 并获取函数指针12345678910111213141516171819202122232425262728293031#include windows.h#include iostream// 定义函数指针类型typedefint(*AddFunc)(int,int);intmain(){HMODULEhDll LoadLibrary(_T(MyDll.dll));// 加载 DLLif(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;// 卸载 DLLFreeLibrary(hDll);return0;}3. 特点优点缺点运行时动态加载灵活使用复杂需手动管理函数指针可判断 DLL 是否存在提供降级方案无编译期检查易出错函数名拼错支持插件系统、热更新、按需加载性能稍低需查表程序可容忍缺失 DLL需要正确处理FreeLibrary防止内存泄漏四、核心区别对比表对比项隐式链接显式链接加载时机程序启动时自动加载运行时手动加载LoadLibrary是否需要 .lib是否可选函数调用方式直接调用如 Add(1,2)通过函数指针调用启动依赖必须存在 DLL否则无法启动可容忍缺失运行时报错灵活性低高可动态选择、卸载、替换适用场景核心功能、稳定依赖插件、可选模块、第三方组件错误处理启动失败可在运行时提示用户性能略高略低需查找符号典型 API无编译器自动处理LoadLibrary, GetProcAddress, FreeLibrary五、如何选择场景推荐方式程序核心功能依赖的 DLL如运行库✅ 隐式链接第三方 SDK、硬件驱动接口✅ 显式链接容错更好实现插件系统如 Photoshop 滤镜✅ 显式链接需要热更新或动态替换模块✅ 显式链接小项目、简单调用、DLL 一定存在✅ 隐式链接更方便六、最佳实践建议优先考虑显式链接用于第三方或可选模块提升程序健壮性。使用 RAII 封装HMODULE避免忘记FreeLibrary12345678classDllLoader {public:DllLoader(constTCHAR* name) { hDll LoadLibrary(name); }~DllLoader() {if(hDll) FreeLibrary(hDll); }HMODULEget() {returnhDll; }private:HMODULEhDll nullptr;};导出 C 函数用extern C避免 C 名称修饰问题。在发布程序时确保 DLL 路径正确当前目录、系统路径、应用程序目录等。
C++中显示与隐式加载dll的使用与区别
一、什么是 DLLDLLDynamic Link Library是 Windows 下的动态链接库包含可被多个程序共享的函数、资源或类。使用 DLL 可以实现代码复用、模块化设计和插件机制。在 C 中调用 DLL 中的函数有两种主要方式隐式链接Implicit Linking显式链接Explicit Linking二、隐式链接Implicit Linking1. 原理程序启动时自动加载 DLL通过.lib导入库将 DLL 中的函数符号链接到可执行文件中。2. 使用步骤1准备三个文件MyDll.dll动态库文件MyDll.lib导入库由 DLL 生成MyDll.h声明导出函数2头文件示例MyDll.h123456789#ifdef __cplusplusexternC{#endif__declspec(dllimport)intAdd(inta,intb);#ifdef __cplusplus}#endif注意dllimport表示从 DLL 导入函数。3链接.lib文件在项目中添加.lib路径并链接1#pragma comment(lib, MyDll.lib)4直接调用函数123#include MyDll.hintresult Add(3, 4);// 直接像普通函数一样调用3. 特点优点缺点使用简单像调用本地函数启动时必须找到 DLL否则程序无法启动编译期检查函数签名不支持动态选择或延迟加载性能略高无需查表难以实现插件系统或热更新三、显式链接Explicit Linking1. 原理运行时通过LoadLibrary和GetProcAddress手动加载 DLL 并获取函数地址。2. 使用步骤1不需要.lib文件只需MyDll.dllMyDll.h知道函数原型2加载 DLL 并获取函数指针12345678910111213141516171819202122232425262728293031#include windows.h#include iostream// 定义函数指针类型typedefint(*AddFunc)(int,int);intmain(){HMODULEhDll LoadLibrary(_T(MyDll.dll));// 加载 DLLif(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;// 卸载 DLLFreeLibrary(hDll);return0;}3. 特点优点缺点运行时动态加载灵活使用复杂需手动管理函数指针可判断 DLL 是否存在提供降级方案无编译期检查易出错函数名拼错支持插件系统、热更新、按需加载性能稍低需查表程序可容忍缺失 DLL需要正确处理FreeLibrary防止内存泄漏四、核心区别对比表对比项隐式链接显式链接加载时机程序启动时自动加载运行时手动加载LoadLibrary是否需要 .lib是否可选函数调用方式直接调用如 Add(1,2)通过函数指针调用启动依赖必须存在 DLL否则无法启动可容忍缺失运行时报错灵活性低高可动态选择、卸载、替换适用场景核心功能、稳定依赖插件、可选模块、第三方组件错误处理启动失败可在运行时提示用户性能略高略低需查找符号典型 API无编译器自动处理LoadLibrary, GetProcAddress, FreeLibrary五、如何选择场景推荐方式程序核心功能依赖的 DLL如运行库✅ 隐式链接第三方 SDK、硬件驱动接口✅ 显式链接容错更好实现插件系统如 Photoshop 滤镜✅ 显式链接需要热更新或动态替换模块✅ 显式链接小项目、简单调用、DLL 一定存在✅ 隐式链接更方便六、最佳实践建议优先考虑显式链接用于第三方或可选模块提升程序健壮性。使用 RAII 封装HMODULE避免忘记FreeLibrary12345678classDllLoader {public:DllLoader(constTCHAR* name) { hDll LoadLibrary(name); }~DllLoader() {if(hDll) FreeLibrary(hDll); }HMODULEget() {returnhDll; }private:HMODULEhDll nullptr;};导出 C 函数用extern C避免 C 名称修饰问题。在发布程序时确保 DLL 路径正确当前目录、系统路径、应用程序目录等。