与 DLL 链接时出现“‘atexit’的多重定义”

Posted

技术标签:

【中文标题】与 DLL 链接时出现“‘atexit’的多重定义”【英文标题】:"multiple definition of `atexit'" when linking with DLL 【发布时间】:2016-08-29 21:51:19 【问题描述】:

我使用 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

我想我必须使用不同的选项来编译库以避免重新定义..

【问题讨论】:

我试过了,但没有解决我的问题... 您应该改进您的问题,显示您尝试过的替代方案。 尝试不使用-D_WIN32 -D_MINGW,我希望任何此类宏都可以内置到编译器构建中 尝试在-l 标志之前使用main.cpp。还要检查“gcc”和“g++”是否都指向同一个安装,并且你的路径是正确的 无变化。顺便说一句,我尝试与 MinGW 一起使用的库 github.com/oblitum/Interception 当我将它与 MSVC 一起使用时,它工作得非常好 【参考方案1】:

我认为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 文件,因此您不必自己构建它们

【讨论】:

我记得我自己解决了这个问题,是的,IIRC 命令有问题。不管怎么说,还是要谢谢你! :)

以上是关于与 DLL 链接时出现“‘atexit’的多重定义”的主要内容,如果未能解决你的问题,请参考以下文章

从 dll 导出 std::vector 时出现链接错误

制作替换系统库中的函数调用的 DLL 时出现问题

打开软件时出现无法定位程序输入点 GetTickCount64 于动态链接库 KERNEL32.dll 上。

安装Qt creator时出现 无法定位程序输入点_except1 于动态链接库MSVCR120.dll上

使用navicate链接oracle时出现问题

将 .NET 4.0 与 dll 一起使用时出现未知错误