You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 19:37:50