Windows下无需CMake/VS,用cl.exe与PowerShell编译链接DLL的问题
问题解答
1. 解决DLL链接错误
你的链接错误是因为链接可执行文件时不能直接使用.dll文件,Windows下链接动态库需要用到对应的导入库(.lib)——编译DLL时,link工具会自动生成这个.lib文件。同时,链接exe时不需要/DLL参数(该参数用于生成DLL,而非可执行文件)。
修改compileAndRun.bat第14行,替换为:
cl /nologo /EHsc /Od /I. build\main.obj /Fe:build\dynamicLibExample.exe /link /LIBPATH:build build\libMyMath.lib
修改后的完整脚本:
@echo off del /q build mkdir build REM 编译源文件为目标文件 cl /nologo /c /EHsc /Od /I. /DCOMPILED lib/myMathLib.cpp /Fobuild\myMathLib.obj cl /nologo /c /EHsc /Od /I. main.cpp /Fobuild\main.obj REM 链接生成DLL,同时自动生成导入库libMyMath.lib link /nologo /DLL /OUT:build\libMyMath.dll build\myMathLib.obj REM 链接目标文件与导入库,生成可执行文件 cl /nologo /EHsc /Od /I. build\main.obj /Fe:build\dynamicLibExample.exe /link /LIBPATH:build build\libMyMath.lib REM 清理目标文件 del build\*.obj REM 运行程序 echo Running dynamic library example build\dynamicLibExample.exe
2. C++项目中是否需要extern "C"
不需要,而且你的代码里用extern "C"包裹C类是无效的——extern "C"仅用于兼容C语言的函数,无法改变C类成员函数的名称修饰规则,类的成员函数依然会按照C++规则生成修饰名。
- 若库仅给C++项目使用:完全可以移除
extern "C",同一编译器下,会自动处理一致的名称修饰,不会出现链接问题。 - 只有需要让C语言调用库时,才需要用
extern "C"导出C风格函数(注意:不能用extern "C"导出类)。
3. 使用DEF文件替代__declspec(dllexport/dllimport)
步骤1:修改头文件
移除所有平台宏和API定义,简化后的myMathLib.h:
// myMathLib.h #pragma once class MyMathLib { public: int add(int a, int b); };
步骤2:创建DEF文件
在lib目录下新建myMathLib.def,内容如下:
LIBRARY libMyMath EXPORTS ?add@MyMathLib@@QEAAHHH@Z @1
(注:?add@MyMathLib@@QEAAHHH@Z是该成员函数的C++修饰名,你可以先编译一次带__declspec(dllexport)的DLL,再用dumpbin /exports build\libMyMath.dll命令查看导出的函数名,复制到DEF文件中)
步骤3:修改编译脚本
去掉/DCOMPILED宏定义,链接DLL时指定DEF文件:
@echo off del /q build mkdir build REM 编译源文件(无需DCOMPILED宏) cl /nologo /c /EHsc /Od /I. lib/myMathLib.cpp /Fobuild\myMathLib.obj cl /nologo /c /EHsc /Od /I. main.cpp /Fobuild\main.obj REM 通过DEF文件链接生成DLL和导入库 link /nologo /DLL /OUT:build\libMyMath.dll /DEF:lib/myMathLib.def build\myMathLib.obj REM 链接生成可执行文件 cl /nologo /EHsc /Od /I. build\main.obj /Fe:build\dynamicLibExample.exe /link /LIBPATH:build build\libMyMath.lib REM 清理并运行 del build\*.obj echo Running dynamic library example build\dynamicLibExample.exe
这样就可以完全不依赖__declspec指令,通过DEF文件实现符号导出。
内容的提问来源于stack exchange,提问作者tom
相关产品推荐
相关产品推荐

