c++代码中对c函数的未定义引用

undefined reference to c functions in c++ code

本文关键字:未定义 引用 函数 代码 c++      更新时间:2023-10-16

我有一个奇怪的问题:下面的代码编译得很好
src.cpp:

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()的未定义引用
有什么解决办法吗?谢谢

更新:
我在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("%dn", a());
printf("%dn", b());
return 0;
}

main2.c:

#include <stdio.h>

int a();
int b();
int main()
{
//printf("%dn", a());
printf("%dn", 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

现在我们编译我们的exec:

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的文件a.o

$nm libb.a
b.o:
U a
0000000000000000 T b

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

当被要求时,链接器不包括整个静态库。它会查找需要哪些.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.o为时已晚,liba.a已经被处理。请注意,当我切换库,它将干净地编译:

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