我有一个奇怪的问题:下面的代码完美编译。
源文件:
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.a
和libb.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
被编译并且它需要 a
和 b
符号。当链接器获取 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
关于c++ - C++ 代码中对 C 函数的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29652966/