在链接目标文件时出现“未定义的引用”错误

9
我知道这个问题已经以多种方式提出,包括这个非常全面的答案,但我查看了很多并尝试修复我的错误,但都没有成功。
我正在使用.cpp和.c文件创建程序。我使用g++编译了所有文件,它似乎没有更多的链接错误,尽管它给了我一堆与C语法相关的C++错误。这是我使用的命令:
g++ -o program main.cpp /data/*.c -l[...libs]

主函数main.cpp调用了.c文件中的函数。 然后我明白了,不应该尝试使用一个编译器同时编译.c和.cpp文件,而是要分别使用gcc和g++,然后链接目标文件即可。 所以我这样做了(.c文件是库的一部分,已经有.o文件)。
g++ -c main.cpp
g++ -o program main.o /data/*.o -l[..libs]

但是,当我从main.cpp调用预编译的.c文件中的函数时,会出现“undefined reference to”错误,而之前没有出现过这些错误。

有人可以帮忙吗?或者我需要提供更多信息吗?

编辑(更详细的代码摘录,我试图简化此处的内容,但如果需要添加其他内容,请告知,我将尝试删除不必要的代码):

main.cpp:

#include "header.h"

int main(int argc, char** argv) {
    string s1 = argv[2];
    fn1(s1)
}

header.h

void fn1(string s1)

mycfile.c

#include "header.h"

void fn1(string s1){
    fprintf(stdout, " you entered %s", s1);
    fflush(stdout);
}

回答:

@Smeehey帮助我找到了解决方案,实际上是因为我仍然在使用一个.hpp文件中包含旧的头文件。但核心解决方案确实是使用外部C{}。


请发布您的代码,通常未定义引用错误是由于将头文件包含到某些代码中而导致对函数/变量的引用,而没有链接实际函数/定义的实际代码。 - DrPrItay
g++ 的参数顺序非常重要,甚至库的顺序也很重要。要更具体一些。此外,始终g++ 传递 -Wall -g - Basile Starynkevitch
3个回答

17

这很可能与C和C++的链接有关。在您的main.cpp中,您可能有如下代码:

#include <data/header.h>

其中 header.h 是您的 C 库。请将其替换为以下内容:

注意:保留原文中的 HTML 标签。

extern "C" {
#include <data/header.h>
}

这告诉你的C++编译器在定义头文件中所需的符号时不要使用C++风格的名称重整,从而使链接器能够成功地在C编译的.o文件中找到它们。


1
当在*c++*编译的目标文件上运行nm命令时,是的,没错。 - Smeeheey
是的,在C++的.o文件上。嗯,那可能是问题的原因,即使我添加了'extern C',我仍然得到了混淆的名称。 - Victor.dMdB
1
你能否发布你的完整代码、命令行和链接器错误信息? - Smeeheey
你的 nm -u 输出中,头文件中哪个符号仍然被混淆了? - Smeeheey
1
你是在你的示例代码还是实际代码中遇到了这个问题?我可以轻松地展示,在我的示例代码版本中,名称修饰已被移除。你的示例代码不可能正常工作(使用 extern "C"),因为你将一个 string 传递给你的函数 fn,我假设它是一个 std::string - 但是这在 extern C 头文件中不起作用,因为它是一个 C++ 模板(除非你使用了一些非平凡的技巧)。 - Smeeheey
显示剩余6条评论

2

您需要使用gcc命令编译C文件,使用gccg++命令编译C++文件,并使用g++命令进行链接。以下是可能有效的编译顺序:

 gcc -c data/*.c main.cpp
 g++ -o program *.o -l <libs...>

下一步:学习编写正确的Makefile。

使用 gcc(而不是 g++)编译 C 文件似乎可以正常工作。然后再使用 g++ 进行链接。 - Yan King Yin

0
这可能是一次瞎猜,但问题可能在于C和Cpp文件的编译方式相似但略有不同......由于名称空间,函数foo将生成符号some_prefix@foo,而不像C那样goo生成符号goo
请尝试在您的.cpp文件中执行以下操作: extern "C" { #include "yourcfilesheader.h" } 并请附上您的代码。

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