CMake在Windows上编译动态库的核心是:使用ADD_LIBRARY(SHARED)生成.dll和.lib,并通过target_compile_definitions定义MYLIB_EXPORT宏以启用__declspec(dllexport)导出函数,否则链接报LNK2019或运行时报“找不到入口点”。

cmake 在 Windows 上编译动态库,核心是让 ADD_LIBRARY 指令生成 SHARED 类型,并正确处理 Windows 特有的符号导出(__declspec(dllexport) / __declspec(dllimport))。不配好导出宏,链接时大概率报 LNK2019 或运行时报“找不到入口点”。
必须加 MYLIB_EXPORT 宏才能导出函数
Windows 动态库(.dll)和其配套的导入库(.lib)依赖显式导出声明。头文件里通常这样写:
#ifdef MYLIB_EXPORT #define MYLIB_API __declspec(dllexport) #else #define MYLIB_API __declspec(dllimport) #endif MYLIB_API int my_add(int a, int b);
编译动态库时,必须在 CMakeLists.txt 中定义该宏:
-
ADD_DEFINITIONS(-DMYLIB_EXPORT)(旧语法,仍可用) - 更推荐:
target_compile_definitions(mylib PRIVATE MYLIB_EXPORT)
漏掉这一步,.dll 里函数不会被导出,下游项目链接时会提示“unresolved external symbol”。
cmake 命令要指定生成器和架构
直接运行 cmake .. 很可能默认调用 MSVC 编译器但没指定平台,导致生成 x86 解决方案却在 x64 环境下构建失败。关键参数必须明确:
-
-G "Visual Studio 17 2022":匹配你装的 VS 版本(VS2019 写"Visual Studio 16 2019") -
-A x64:强制目标为 64 位(Win32表示 x86) -
-DBUILD_SHARED_LIBS=ON:确保全局启用动态库构建 -
-DCMAKE_INSTALL_PREFIX=../install:避免污染源码目录,安装路径建议用相对路径
完整命令示例:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
mkdir build && cd build cmake .. -G "Visual Studio 17 2022" -A x64 -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=../install
编译后要检查 .dll 是否真有导出函数
生成完 .dll 不能直接认为成功。Windows 下用 dumpbin /exports 验证:
dumpbin /exports mylib.dll
如果输出里没有 my_add、my_sub 这类函数名,说明导出失败。常见原因:
- 头文件里没用
MYLIB_API修饰函数声明 -
CMakeLists.txt忘了加MYLIB_EXPORT宏定义 - 函数用了 C++ 名字修饰(如重载、模板),又没加
extern "C",导致导出名变形(例如变成?my_add@@YAHHH@Z)
若需 C 兼容接口,导出函数前加 extern "C",并确保头文件被 C++ 和 C 代码都能安全包含。
链接时别混淆 .lib 和 .dll 的用途
Windows 动态库编译后产出两个关键文件:
-
mylib.lib:导入库,仅含符号表,供链接阶段使用(target_link_libraries(myapp mylib)实际链接它) -
mylib.dll:真正代码,运行时加载,必须放在可执行文件同目录或系统 PATH 中
常见错误是只拷了 .dll 却没在项目里链接 .lib,或者反过来——链接了 .lib 但运行时找不到 .dll,报错 0xc000007b 或“找不到指定模块”。
MYLIB_EXPORT 宏的位置和作用域,最容易在跨项目复用时被忽略。

















