链接DLL时出现“atexit的多重定义”错误

3

我使用MinGW32,更具体地说是TDM-GCC-32。我的项目非常简单,我链接了一个自定义库,但是却出现了这个错误:

>g++ -D_WIN32 -D_MINGW -lgdi32 -lgdiplus -Linterception/x86 -linterception main.cpp -o interceptor.exe

interception/x86/libinterception.a(dgnes00125.o):(.text+0x0): multiple definitio
n of `atexit'
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../crt2.o:crt1.c:(.text+0x2c0):
 first defined here
interception/x86/libinterception.a(dgnes00109.o):(.text+0x0): multiple definitio
n of `_onexit'
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../crt2.o:crt1.c:(.text+0x2d0):
 first defined here
C:/TDM-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../../mingw32/bin/ld.exe: C:/TD
M-GCC-32/bin/../lib/gcc/mingw32/5.1.0/../../../crt2.o: bad reloc address 0x20 in
 section `.eh_frame'
collect2.exe: error: ld returned 1 exit status

我用来构建库的命令:

gcc -DINTERCEPTION_EXPORT -D_WIN32 -D_MINGW -shared -o interception.dll interception.c
dlltool -z interception.def --export-all-symbol interception.dll
dlltool -d interception.def -l libinterception.a

我猜我需要使用不同的选项来编译库以避免重新定义。

我尝试过它们,但并没有解决我的问题... - Konrad
你应该改进你的问题,展示一下你尝试过的替代方案。 - πάντα ῥεῖ
尝试不使用“-D_WIN32 -D_MINGW”,我期望这些宏已经内置于编译器构建中。 - M.M
尝试将 main.cpp 放在 -l 标志之前。还要检查 "gcc" 和 "g++" 是否指向同一个安装位置,并确保路径正确。 - M.M
顺便说一下,我正在尝试在MinGW中使用的库是https://github.com/oblitum/Interception。当我在MSVC中使用它时,它完美地工作了。 - Konrad
1个回答

2
我认为目前dlltool方法已经被弃用。但我不怪你,因为大部分可用的文档仍然建议使用这种方式。
Gcc将直接链接.dll文件,使得.a文件过时了(至少在处理dll方面是这样的——当前唯一使用.a文件的原因是进行静态链接)。即使您不使用-l标志指定dll,也可以直接链接。但是如果dll不在当前目录中,则必须指定dll的路径。
C:\Users\burito>gcc main.o opengl32.dll -o main.exe
gcc: error: opengl32.dll: No such file or directory

C:\Users\burito>gcc main.o c:\Windows\system32\opengl32.dll -o main.exe

C:\Users\burito>

好的,opengl32.dll 或许不是一个很好的例子,但我希望你能理解我的意思。

我认为 MSVC 仍然需要它的 .lib 文件来使用一个 .dll,如果库文件没有附带,则有几种方法可以制作它们。

在您的特定情况下,应该可行的命令是...

g++ -D_WIN32 -D_MINGW -lgdi32 -lgdiplus interception/x86/interception.dll main.cpp -o interceptor.exe

如果由于某种原因你确实需要从 .dll 文件创建一个 .a 文件,那么对我有效的命令是...
gendef interception.dll
dlltool -l interception.a -d interception.def -k -A

由于您链接的仓库在其发布中提供了.dll文件,因此您不需要自己构建它们。

我记得我自己解决了这个问题,好像是命令有问题。不管怎样,还是谢谢! :) - Konrad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接