c++ - C++ 代码中对 C 函数的 undefined reference

标签 c++ linkage

我有一个奇怪的问题:下面的代码完美编译。
源文件:

extern "C" {
    #include "header.h"
}

void A::Execute() {
    B::Instance().Reset(ix);
    c_func(ix);// this is c functions declared in header.h
    C::Instance().Erase(ix);
}

但是当我注释掉 c_funk() 时,我在所有使用 header.h 文件中的 c 函数的地方都出现了链接错误。

有了这个小改动:

void A::Execute() {
    B::Instance().Reset(ix);
    //c_func(ix);// this is c function declared in header.h
    C::Instance().Erase(ix);
}

我得到:对 c_func() 的 undefined reference 。
任何想法如何解决它?谢谢。

更新:
我在 header.h 中添加了一个虚拟函数:foo_for_linkage_problem();
并以这种方式解决了问题。据我了解,链接器会尝试进行一些优化来解决此问题。新代码:

void A::Execute() {
    B::Instance().Reset(ix);
    foo_for_linkage_problem();// this is c empty function declared in header.h 
    C::Instance().Erase(ix);
}

最佳答案

tldnr:您在将库提供给链接器的顺序上有问题。

我想我知道哪里出了问题。假设您有四个文件:

main.c:

#include <stdio.h>
    
int a();
int b();

int main()
{
    printf("%d\n", a());
    printf("%d\n", b());

    return 0;
}

main2.c:

#include <stdio.h>
    
int a();
int b();

int main()
{
    //printf("%d\n", a());
    printf("%d\n", b());

    return 0;
}

a.c:

int a()
{
    return 67;
}

b.c:

int a();

int b()
{
    return a()+5;
}

我们创建liba.alibb.a:

gcc a.c -c -o a.o
gcc b.c -c -o b.o
ar rcs liba.a a.o
ar rcs libb.a b.o

现在我们编译我们的执行程序:

gcc main.c liba.a libb.a -o test

一切正常

gcc main2.c liba.a libb.a -o test

我得到:

libb.a(b.o): In function `b':
b.c:(.text+0xa): undefined reference to `a'
collect2: error: ld returned 1 exit status

让我们检查一下我的库提供/需要哪些符号:

$nm liba.a

a.o:
0000000000000000 T a

符号类型 T 表示该库有文件 a.o 提供符号 a

$nm libb.a

b.o:
                 U a
0000000000000000 T b

libb.a 包含文件 b.o,它提供符号 b 但需要符号 a

链接器在询问时不包括整个静态库。它会查找需要哪些 .o 文件并仅链接那些文件。因此,您提供文件的顺序至关重要。

当执行下面的命令时,main.c 被编译并且它需要 ab 符号。当链接器获取 liba.a 库时,它会链接 a.o 文件,因为它提供了 a 符号。当链接器获取 libb.a 库时,它会链接 b.o 文件,因为它提供了 b 符号。一切正常。

gcc main.c liba.a libb.a -o test

当执行 main2 命令时,main2.c 被编译,它只需要 b 符号。当链接器获取 liba.a 时,它不会链接 a.o,因为根本不需要 a。然后链接器获取 libb.a 库,它链接 b.o 文件,因为它提供了 b 符号。但是b.o文件需要符号a,来不及链接a.oliba.a已经处理。请注意,当 我切换库,它将干净地编译:

gcc main2.c libb.a liba.a -o test

关于c++ - C++ 代码中对 C 函数的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29652966/

相关文章:

java - java.util.function.Supplier 的 C++ 等价物是什么?

c++ - 我可以使用 typedef 转发声明在别处定义的类型吗

c++ - C++中extern "C"有什么作用?

c - 了解标识符的链接

C++:值的名称可能有链接

c++ - 我对 N4140 中 [basic.link]/7 的理解是否正确?

c++ - 围绕 avcodec_open/close 的线程锁定

c++ - 非静态或常量数组语法

c++ - std::lower_bound 中使用的比较运算符

linux - GCC - 动态依赖