如何在Windows下用c++调用DLL动态链接库 显式链接和隐式链接【教程】

发布时间 - 2025-12-25 00:00:00    点击率:
Windows下C++调用DLL有隐式链接和显式链接两种方式:前者编译时绑定,需DLL、.lib和头文件,调用简单但路径固定;后者运行时用LoadLibrary/GetProcAddress加载,灵活适用于插件等场景,需注意名称修饰、路径、位数匹配等问题。

在 Windows 下用 C++ 调用 DLL,主要有两种方式:隐式链接(静态链接导入)和显式链接(运行时加载)。区别在于链接时机和灵活性——隐式链接编译时就绑定 DLL,简单但依赖固定路径;显式链接在运行时用 LoadLibraryGetProcAddress 手动加载,更灵活,适合插件机制或避免启动失败。

隐式链接:编译期绑定,用起来最简单

隐式链接需要三样东西:DLL 文件、对应 .lib 导入库(由 DLL 生成)、以及头文件(声明导出函数)。编译器靠 .lib 知道函数签名和符号名,链接器在生成 EXE 时写入导入表,系统启动时自动加载 DLL。

  • 确保 DLL 已正确导出函数(用 __declspec(dllexport) 或 .def 文件)
  • 把 DLL 放在可执行文件同目录、系统 PATH 路径,或 Windows 系统目录下
  • 在 C++ 代码中 #include 对应头文件,并链接 .lib(如 project.lib
  • 直接调用函数,像调用普通函数一样,无需手动加载

例如:int result = MyAdd(3, 5); —— 只要头文件里声明了 MyAdd,且链接了 mylib.lib,就能工作。

显式链接:运行时加载,控制力更强

显式链接不依赖 .lib,完全靠 Win32 API 在运行时操作。适合需要按需加载、容错处理(比如 DLL 缺失时友好提示)、或多版本共存的场景。

  • HMODULE hLib = LoadLibrary(L"mylib.dll"); 加载 DLL(注意宽字符)
  • 检查返回值:为 NULL 表示失败,可用 GetLastError() 查原因
  • GetProcAddress(hLib, "MyAdd") 获取函数地址,强转为对应函数指针类型
  • 调用前务必判空,防止崩溃;用完后调用 FreeLibrary(hLib) 卸载

小技巧:函数指针类型建议用 typedefusing 定义,比如 using AddFunc = int(*)(int, int);,让代码更清晰安全。

导出函数要注意名字修饰(Name Mangling)

C++ 编译器会对函数名做修饰(比如加参数类型信息),导致 GetProcAddress 找不到原始名字。解决方法有二:

  • extern "C" 包裹导出函数声明,禁用 C++ 名字修饰(推荐用于 C 风格接口)
  • 用 .def 文件显式指定导出名,绕过编译器修饰(适合必须用 C++ 成员函数的场景)

验证导出名是否正确?可用 dumpbin /exports mylib.dll(VS 工具)或 Dependency Walker 查看实际导出符号。

常见坑和调试建议

很多初学者卡在“找不到 DLL”或“找不到过程入口”,其实多数是路径或符号问题:

  • DLL 路径不对:显式链接时传绝对路径最稳妥;隐式链接优先查当前目录 → PATH → 系统目录
  • 位数不匹配:32 位程序不能加载 64 位 DLL,反之亦然(检查项目平台设置)
  • 依赖缺失:用 Dependencies.exe(现代版 Dependency Walker)查看 DLL 是否还缺其他依赖项
  • Unicode/ANSI 混淆:LoadLibrary 推荐用 LoadLibraryW + L"xxx.dll",避免多字节编码陷阱

写个简单的封装类或 RAII 封装 HMODULE,能显著减少资源泄漏和重复判断。


# windows  # cad  # 编码  # 字节  # 工具  # ai  # c++  # win  # 解决方法  # 区别  # typedef  # lsp  # NULL  # 封装  # 成员函数  # include  # extern  # int  # 指针  # 接口  # using  # 指针类型  # 加载  # 隐式  # 找不到  # 头文件  # 绑定  # 多字  # 时用  # 放在  # 就能  # 两种 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 香港服务器网站卡顿?如何解决网络延迟与负载问题?  香港网站服务器数量如何影响SEO优化效果?  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  西安专业网站制作公司有哪些,陕西省建行官方网站?  网站制作价目表怎么做,珍爱网婚介费用多少?  无锡营销型网站制作公司,无锡网选车牌流程?  JavaScript如何实现音频处理_Web Audio API如何工作?  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  敲碗10年!Mac系列传将迎来「触控与联网」双革新  Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID  如何用腾讯建站主机快速创建免费网站?  ,在苏州找工作,上哪个网站比较好?  零基础网站服务器架设实战:轻量应用与域名解析配置指南  香港服务器选型指南:免备案配置与高效建站方案解析  jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】  Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑  如何在HTML表单中获取用户输入并结合JavaScript动态控制复利计算循环  如何在IIS7上新建站点并设置安全权限?  Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  如何实现建站之星域名转发设置?  Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】  香港服务器WordPress建站指南:SEO优化与高效部署策略  Laravel如何生成PDF或Excel文件_Laravel文档导出工具与使用教程  Laravel怎么使用Intervention Image库处理图片上传和缩放  微信小程序 require机制详解及实例代码  javascript中的try catch异常捕获机制用法分析  如何在 Pandas 中基于一列条件计算另一列的分组均值  googleplay官方入口在哪里_Google Play官方商店快速入口指南  Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门  新三国志曹操传主线渭水交兵攻略  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  Laravel如何创建自定义Artisan命令?(代码示例)  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  实例解析Array和String方法  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  怎样使用JSON进行数据交换_它有什么限制  Android Socket接口实现即时通讯实例代码  Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  微信小程序 input输入框控件详解及实例(多种示例)  Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理  iOS中将个别页面强制横屏其他页面竖屏  Bootstrap整体框架之JavaScript插件架构  JavaScript常见的五种数组去重的方式  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  高防服务器租用指南:配置选择与快速部署攻略  laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?