新建DLL项目须选Dynamic Link Library模板,配置Configuration Type为Dynamic Library,定义MATH_UTILS_EXPORTS宏,导出函数需用extern "C"和__declspec(dllexport)配合,验证用dumpbin /exports,调用时注意隐式链接的.lib路径和运行时库一致。

Visual Studio 项目配置:DLL 工程怎么建才对
新建项目必须选 Dynamic Link Library (.dll) 模板,不是空项目或控制台应用。创建后默认生成的 dllmain.cpp 只负责模块加载通知,不写业务逻辑;导出函数得自己加新源文件(比如 math_utils.cpp)。
关键点在项目属性设置:
-
Configuration Properties → General → Configuration Type必须是Dynamic Library (.dll) -
C/C++ → Preprocessor → Preprocessor Definitions加上MATH_UTILS_EXPORTS(自定义宏名,后续用于条件导出) -
Linker → Advanced → Import Library保持默认即可,VS 会自动生成 .lib 文件
__declspec(dllexport) 怎么加才不报错
导出函数不能只写声明,必须在定义处加修饰符,且要和预处理宏配合,否则头文件被 EXE 和 DLL 同时包含时会冲突。
典型写法:
立即学习“C++免费学习笔记(深入)”;
#ifdef MATH_UTILS_EXPORTS #define MATH_API __declspec(dllexport) #else #define MATH_API __declspec(dllimport) #endifextern "C" MATH_API int add(int a, int b);
注意三点:
- 用
extern "C"防止 C++ 名字改编(name mangling),否则 C# 或 C 调用时找不到符号 -
MATH_UTILS_EXPORTS只在 DLL 工程中定义,EXE 工程不定义,这样头文件里MATH_API在 DLL 编译时展开为dllexport,在 EXE 中展开为dllimport - 类导出更复杂,需整个类加
__declspec(dllexport),且所有成员函数都受控,一般建议只导出 C 风格函数
生成后怎么验证函数真导出了
光有 .dll 文件不够,得确认符号确实存在。Windows 自带工具 dumpbin 最直接:
dumpbin /exports mymath.dll
输出里应看到类似:
ordinal hint RVA name
1 0 00011000 ?add@@YAHHH@Z ← C++ 编译后的名字(没加 extern "C")
1 0 00011000 add ← 加了 extern "C" 后的干净名字
如果只看到一堆问号或乱码,大概率漏了 extern "C";如果完全没列出函数名,检查是否忘了 __declspec(dllexport) 或拼写错误(比如宏名大小写不一致)。
调用方(EXE)怎么链接和加载 DLL
有两种方式:隐式链接(推荐新手)和显式加载(LoadLibrary)。隐式链接更简单但要求运行时 DLL 在 PATH 或同目录:
- EXE 工程里添加
#include "math_utils.h",并把 DLL 对应的.lib文件路径加到Linker → General → Additional Library Directories - 在
Linker → Input → Additional Dependencies里填mymath.lib - 确保运行 EXE 前,
mymath.dll在当前目录或系统 PATH 下,否则报错The code execution cannot proceed because mymath.dll was not found
显式加载适合插件场景,但要用 GetProcAddress 手动取函数地址,类型转换容易出错,稍不注意就崩。
最容易被忽略的是:DLL 和 EXE 必须用同一套运行时(/MT 或 /MD),混用会导致内存分配崩溃或静态变量不共享。检查方法是看双方项目属性里 C/C++ → Code Generation → Runtime Library 是否一致。










