news 2026/5/1 5:24:34

C / C++ 调用 DLL 的几种常见方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C / C++ 调用 DLL 的几种常见方法

C / C++ 调用 DLL 的几种常见方法(详解 + 示例)

在 Windows 平台开发中,DLL(Dynamic Link Library,动态链接库)是非常核心的一种代码复用方式。

无论是:

  • 调用第三方 SDK
  • 拆分大型工程
  • 插件化设计
  • COM / OPC / 工控 / 驱动相关开发

都会不可避免地用到C / C++ 调用 DLL

本文将从零基础视角出发,系统讲清楚:

  • DLL 是什么
  • C/C++ 调用 DLL 的 3 种主流方式
  • 每种方式的使用场景
  • 常见坑点与避坑建议

一、DLL 是什么?(一句话理解)

DLL 是一个“在运行时被加载的函数集合”

和静态库(.lib)的核心区别:

项目DLL静态库
链接时间运行时编译期
文件.dll + .lib.lib
更新可单独替换需重新编译
内存多进程共享各自一份

二、最基础示例:先做一个 DLL

1、 编写 DLL 源码

// mydll.h#pragmaonce#ifdefMYDLL_EXPORTS#defineMYDLL_API__declspec(dllexport)#else#defineMYDLL_API__declspec(dllimport)#endifextern"C"MYDLL_APIintAdd(inta,intb);
// mydll.cpp#defineMYDLL_EXPORTS#include"mydll.h"intAdd(inta,intb){returna+b;}

关键点解释:

  • __declspec(dllexport):导出函数
  • __declspec(dllimport):导入函数
  • extern "C":防止 C++ 名字修饰(非常重要)

2、 编译生成

打开 VS 开发者命令行,在开始菜单中找到并打开:

x64 Native Tools Command PromptforVS2022

注意位数:

  • x86 DLL → 用 x86 Native Tools
  • x64 DLL → 用 x64 Native Tools

使用cl.exe生成DebugDLL(带 PDB)

  1. 最常用 Debug 编译命令(推荐)
cl /LD /Zi /Od /MDd /EHsc mydll.cpp

各参数含义,编译选项参数说明

参数含义
/LD生成 DLL
/Zi生成调试信息(PDB)
/Od关闭优化(便于调试)
/MDd使用 Debug CRT(msvcrtd.dll)
/EHsc标准 C++ 异常处理(推荐)
D:\test\dll>cl /LD /Zi /Od /MDd /EHsc mydll.cpp 用于 x86 的 Microsoft(R)C/C++ 优化编译器19.50.35720 版 版权所有(C)Microsoft Corporation。保留所有权利。 mydll.cpp Microsoft(R)Incremental Linker Version14.50.35720.0 Copyright(C)Microsoft Corporation. All rights reserved. /out:mydll.dll /dll /implib:mydll.lib /debug mydll.obj D:\test\dll>

编译结果

mydll.dll ← Debug DLL
mydll.lib ← 导入库
mydll.pdb ← 调试符号文件(关键)

  1. 指定 Debug 输出目录
cl /LD /Zi /Od /MDd mydll.cpp ^ /Fe:Debug\mydll.dll ^ /Fd:Debug\mydll.pdb

生成结果:

Debug\├── mydll.dll ├── mydll.lib └── mydll.pdb
  1. Release 版对照
cl /LD /O2 /MD mydll.cpp
DebugRelease
/Zi /Od /MDd/O2 /MD
有 pdb可选 pdb
可单步优化后难调试

编译选项参数说明

最终你会得到:

mydll.dll mydll.lib

三、方式一:隐式链接(最推荐,最常用)

适用场景

  • DLL 在开发时就确定
  • SDK / 内部模块
  • 不需要动态卸载

1、调用方代码

#include<iostream>#include"mydll.h"intmain(){intr=Add(2,3);std::cout<<"result = "<<r<<std::endl;return0;}

2、工程设置(Visual Studio)

添加 lib:
  • 项目属性
  • 链接器 → 输入 → 附加依赖项
  • 添加:mydll.lib
放置 dll:
  • mydll.dll放在:

    • exe 同目录
    • 或 PATH 目录

优点

  • 语法最简单
  • 编译期检查函数签名
  • 性能最好

缺点

  • DLL 缺失 → 程序启动直接失败

四、方式二:显式加载(LoadLibrary / GetProcAddress)

适用场景

  • 插件系统
  • 可选功能
  • DLL 可能不存在
  • 逆向 / 热更新 / 工控系统常用

示例代码

#include<windows.h>#include<iostream>typedefint(*AddFunc)(int,int);intmain(){HMODULE hDll=LoadLibraryA("mydll.dll");if(!hDll){std::cout<<"LoadLibrary failed"<<std::endl;return-1;}AddFunc Add=(AddFunc)GetProcAddress(hDll,"Add");if(!Add){std::cout<<"GetProcAddress failed"<<std::endl;FreeLibrary(hDll);return-1;}intr=Add(3,4);std::cout<<"result = "<<r<<std::endl;FreeLibrary(hDll);return0;}

关键注意点

  1. 函数名必须是导出名

    • C++ 函数如果没有extern "C",名字会被修饰
  2. 函数指针签名必须完全一致,可以使用下面的命令查看函数指针签名

    dumpbin /exports mydll.dll

  1. 调用约定要一致(__cdecl / __stdcall

优点

  • 程序可在 DLL 缺失时继续运行
  • 灵活性极高

缺点

  • 写法复杂
  • 容易崩溃(函数签名不匹配)

五、方式三:DLL + .lib,但运行时可选(进阶)

这是方式一和方式二的混合体

  • 编译期链接.lib
  • 运行时通过LoadLibrary判断是否可用

适合大型工程 / 插件化 SDK。


六、C++ 类如何导出 / 调用?

1、DLL 导出类(示例)

class__declspec(dllexport)MyClass{public:intAdd(inta,intb);};

不推荐直接跨 DLL 导出 C++ 类,原因:

  • ABI 不稳定
  • 编译器 / STL 版本耦合
  • 内存管理容易炸

工程实践建议:

DLL 对外只暴露 C 接口,内部再用 C++


七、常见坑点总结(新手必看)

1、忘记 extern “C”

extern"C"__declspec(dllexport)intFunc();

否则GetProcAddress很容易失败。


2、32 位 / 64 位不匹配

  • 32 位 exe ❌ 加载 64 位 dll
  • 会直接LoadLibrary失败

dumpbin /headers xxx.dll查看位数


3、 调用约定不一致

__stdcall vs __cdecl

不一致 → 栈损坏 → 程序随机崩溃


4、 DLL 放置路径错误

Windows 查找 DLL 顺序:

  1. exe 同目录
  2. 系统目录
  3. PATH 环境变量

八、如何查看 DLL 导出函数?(实用技巧)

dumpbin /exports mydll.dll

可以看到:

  • 函数名
  • 序号
  • 是否被修饰

这是调试GetProcAddress的神器。


九、实际工程建议(经验总结)

  • 新项目:优先 extern “C” + 隐式链接
  • 插件系统:显式加载
  • 不要跨 DLL 传 STL 容器
  • 不要在不同 CRT 中 free 内存

十、总结一句话

DLL 是 Windows 下模块化的核心能力,
会用 DLL,才算真正进入 C/C++ 工程开发。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 5:23:25

基于SSM的一站式酒店管理系统

基于SSM的一站式酒店管理系统设计与实现 一、系统开发背景与核心价值 随着旅游业与商务出行的持续升温&#xff0c;酒店行业迎来规模化发展的同时&#xff0c;也面临着管理效率低、服务流程不规范、客户体验参差不齐等问题。传统酒店管理模式依赖人工记录订单、统计房源、核对账…

作者头像 李华
网站建设 2026/4/30 4:32:38

基于WEB的大学生心理互助社区

基于WEB的大学生心理互助社区设计与实现 一、社区开发背景与核心价值 当前大学生面临学业压力、人际关系、就业焦虑等多重心理挑战&#xff0c;传统心理支持模式存在资源有限、求助门槛高、隐私保护不足等问题。线下心理咨询预约难、咨询时段固定&#xff0c;部分学生因顾虑隐私…

作者头像 李华
网站建设 2026/4/23 15:45:57

FastAPI 入门指南

FastAPI 是近年来 Python 生态中增长最快的 Web 框架之一&#xff0c;因其高性能、强类型、自动化文档、优秀的异步支持&#xff0c;已成为构建 API 服务、AI 推理接口、数据服务的主流选择。 本文将从纯后端技术视角系统介绍 FastAPI 的核心能力、设计理念与工程化实践&#…

作者头像 李华
网站建设 2026/4/22 21:42:54

LangChain vs Dify:大模型应用开发工具选择指南,看完就会用!

简介 LangChain是面向开发者的开源代码框架&#xff0c;提供高度灵活的定制能力&#xff1b;Dify是低代码平台&#xff0c;通过可视化操作实现快速应用开发。LangChain适合复杂定制和高性能需求场景&#xff0c;Dify适合快速落地和非技术团队使用。二者结合可实现核心定制与便捷…

作者头像 李华
网站建设 2026/4/26 16:01:56

市场化技术转移机构如何借助AI赋能科技治理系统突破传统路径依赖,继而打造轻量级的成果转化成功率?

观点作者&#xff1a;科易网AI技术转移研究院在当前科技创新体系下&#xff0c;高校作为科技成果的重要产出地&#xff0c;其科技成果转化工作的重要性日益凸显。然而&#xff0c;长期以来&#xff0c;高校科技成果转化面临着诸多挑战&#xff0c;如转化机制不健全、队伍建设不…

作者头像 李华
网站建设 2026/4/23 17:29:00

为地方政府选择AI赋能科技治理系统,需要关注哪些核心要点?

观点作者&#xff1a;科易网AI技术转移研究院近年来&#xff0c;随着国家对科技创新的日益重视&#xff0c;高校作为科技成果的重要产出地&#xff0c;其科技成果转化工作也迎来了新的发展机遇。然而&#xff0c;长期以来&#xff0c;“转化难”的问题始终困扰着高校&#xff0…

作者头像 李华