Windows下使用MinGW链接自定义DLL时出现未定义引用错误的求助
我来帮你解决这个问题!你遇到的未定义引用错误,主要是MinGW在处理C++ DLL的名字修饰和导入库生成这两个环节出了点小问题,咱们一步步来修复:
1. 先搞定DLL的导入库生成
你之前编译DLL的命令只生成了dll.dll,但MinGW链接C++程序时需要对应的导入库文件(libdll.a)——这个文件是链接器用来定位DLL中函数入口的关键。修改你的编译命令:
首先编译dll.cpp为目标文件:
g++ -c dll.cpp -o dll.o
然后生成DLL的同时,让链接器输出导入库:
g++ --shared -o dll.dll dll.o -Wl,--out-implib,libdll.a
执行完这两条命令后,你的文件夹里会多出一个libdll.a文件,这就是咱们链接时需要的导入库。
2. 解决C++函数的名字修饰问题
错误信息里的_imp___Z8sayHiv是C编译器对sayHi函数做的**名字修饰(name mangling)**结果——因为C支持函数重载,编译器会给函数名加上额外的标识,但这会导致链接时找不到对应的导入函数。咱们可以用extern "C"来强制让函数以C语言的方式导出,避免名字被混淆:
修改你的dll.cpp代码:
#include <iostream> #include <windows.h> using namespace std; extern "C" __declspec (dllexport) void sayHi (void) { cout << "Hi" << endl; }
对应的main.cpp也要同步修改:
#include <iostream> #include <windows.h> using namespace std; extern "C" __declspec(dllimport) void sayHi(void); int main () { sayHi(); }
3. 正确链接main.cpp
现在有了正确的导入库,用下面的命令编译链接main.cpp:
g++ main.cpp -o main.exe -L. -ldll
这里的-L.是告诉链接器在当前目录下查找导入库(因为libdll.a就在你的文件夹里),-ldll则是指定要链接的库为libdll.a(MinGW会自动把-lxxx映射到libxxx.a)。
4. 运行程序的小提醒
编译出main.exe后,要确保dll.dll和main.exe在同一个目录下,或者把dll.dll放到系统能自动找到的路径(比如Windows的System32文件夹),否则运行程序时会提示找不到DLL文件。
按照上面的步骤重新操作一遍,应该就能成功调用DLL里的sayHi函数,输出"Hi"啦!
备注:内容来源于stack exchange,提问作者nico0xB




