gcc:在 C++ 应用程序中链接 C 库会导致“多重定义”错误

Posted

技术标签:

【中文标题】gcc:在 C++ 应用程序中链接 C 库会导致“多重定义”错误【英文标题】:gcc: Linking C library in a C++ app results in "multiple definition of" errors 【发布时间】:2011-05-17 23:26:41 【问题描述】:

我有一个可用的 C 库,我想使用 gcc 链接到 C++ 应用程序,但链接器 (g++) 给了我“多重定义”错误。使用 C 应用程序和 gcc 它可以工作。 定义接口的头文件都包含:

#ifdef __cplusplus 
extern "C" 
#endif

我使用“nm”命令检查了库,它确实有多个方法定义(有问题的方法不是来自公共接口)。

我的问题是:

    为什么我的库有多个定义(有些是 T,有些是 U)?

    如果包含文件的应用程序是 C 应用程序(我正在使用 -Wall 构建),为什么它可以工作?

    我是否需要任何特殊属性或使用特定的文件扩展名才能使其工作,或者我需要回到编程学校:)?

更加注意 lib.a 文件,我可以看到其中一个对象被包含两次。例如,我对同一个对象有两个部分:

 obj1.o
 00000000     T    Method

 obj2.o
 00000000     T    Hello

 obj1.o
 00000000     T    Method

我猜这是问题所在?

非常感谢任何帮助。

【问题讨论】:

为了清楚起见。多个符号是来自库的公共接口(即头文件中的内容)还是来自标准库的东西? 您是否使用所有相同的设置进行构建?一些设置会导致二进制文件不兼容——即默认调用约定等。 致 Laserallan - 好问题。重复的符号来自标准库的东西。 致 Billy ONeal - 是的,相同的设置,只是使用 -I 和 -L,没什么特别的。 在制作 C++ 应用程序时,您在哪里使用 gcc 和/或 g++?假设您有源文件cLib.ccApp.ccppApp.cpp。如果你尝试这个,我认为它有效? gcc cLib.c -o cLib.o; gcc cApp.c -o cApp.o; gcc cLib.o cApp.o -o cApp.exe但这失败了?:gcc cLib.c -o cLib.o; g++ cppApp.cpp -o cppApp.o; g++ cLib.o cppApp.o -o cppApp.exe 【参考方案1】:

我的猜测是“#define BLAHBLAH_H”和“#ifndef BLAHBLAH_H / #endif”设置在“extern“C”'之外。

【讨论】:

太狂野了 :) 有问题的方法不是公开的,因此它们的标头不需要 extern C 的东西。 (至少据我所知不是)。 我不是很精通 cpp。然而,在 C 中,extern 关键字仅仅意味着变量/函数在某处声明,因此,它是在本地声明的,而不给出实际定义。如果没有其他工作,它可能值得一试。 :P 我期待看到真正的原因和解决方案。【参考方案2】:

在玩了之后,我发现实际上整个命令行(它是一种具有自动编译和链接的复杂应用程序)在包含 C 库之前包含 --whole-archive 参数。在 --no-whole-archive 之后移动库解决了问题。

原始命令

   gcc -Wl,**--whole-archive** -l:otherlibs *-Llibpath -l:libname* Wl,**--no-whole-archive** -o myApp hello.c

固定命令

   gcc -Wl,**--whole-archive** -l:otherlibs Wl,**--no-whole-archive** *-Llibpath -l:libname* -o myApp hello.c

感谢大家的帮助,如果我没有提供足够/准确的信息,我们深表歉意。

最好的问候

【讨论】:

以上是关于gcc:在 C++ 应用程序中链接 C 库会导致“多重定义”错误的主要内容,如果未能解决你的问题,请参考以下文章

gcc,c++:静态字符串成员变量导致堆损坏/分段错误

GCC 优化在运行时导致“未定义的符号”

可以跨 C 和 C++ 方法优化 gcc 或 clang 的 LTO

由于C++类库版本不同导致的OpenCV编译链接错误

gcc和g++的区别解析

具有 GCC 优化的 C++ 代码导致核心在字符串上具有无效的 free()