最小示例
dllmain.cpp:
#include <windows.h>
#include <stdio.h>
extern "C" __declspec(dllexport)
void HelloFromDll() {
MessageBoxA(NULL, "Hello from DLL", "DLL", MB_OK);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved) {
return TRUE;
}
MSVC cl.exe 编译
cl /LD /EHsc /Y- dllmain.cpp user32.lib
参数说明:
| 参数 | 含义 |
|---|---|
/LD | 编译为 DLL(输出 .dll + .lib) |
/LDd | Debug 版 DLL |
/EHsc | 启用 C++ 标准异常处理 |
/Y- | 禁用预编译头(避免找不到 pch.h) |
user32.lib | 链接 user32(MessageBox 所在库) |
必须在正确的命令提示符里运行
普通 cmd 里没有 cl 命令,必须用:
开始菜单 → Visual Studio 20xx → x64 Native Tools Command Prompt for VS 20xx
或在普通 cmd 里手动初始化:
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
cl /LD /EHsc /Y- dllmain.cpp user32.lib
vcvars64.bat 路径随 VS 版本和安装目录变化,注意替换。
输出文件
成功后生成:
dllmain.dll— 动态链接库dllmain.lib— 导入库(供其他项目链接用)dllmain.exp— 导出表
MinGW g++ 编译(不需要 VS)
安装 MinGW 后:
g++ -shared -o test.dll dllmain.cpp -luser32
或指定目标架构:
x86_64-w64-mingw32-g++ -shared -o test.dll dllmain.cpp -luser32
MinGW 编译的 DLL 默认导出所有 extern "C" 函数,不需要 .def 文件。
预编译头问题(/Y-)
VS 新建项目默认启用预编译头,会生成 pch.h 和 pch.cpp。手写 .cpp 文件如果没有包含 pch.h,编译时报:
fatal error C1010: unexpected end of file while looking for precompiled header
解决方法:
- 加
/Y-禁用预编译头(适合独立小文件) - 在每个
.cpp第一行加#include "pch.h" - 在文件属性里设置「不使用预编译头」
导出函数声明
C++ 有 name mangling,跨语言调用需要 extern "C" 防止符号被修饰:
// 头文件
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
extern "C" MYDLL_API int Add(int a, int b);
用 .def 文件显式指定导出名(不受 extern “C” 影响):
LIBRARY mydll
EXPORTS
Add @1
Hello @2
编译时加 /DEF:mydll.def。
验证导出
dumpbin /exports dllmain.dll
或用 Dependency Walker、x64dbg 查看导出表。
