链接找不到符号的两种表现
本文分析链接时找不到符号时的两个不同表现,帮助快速定位问题。
结论
如果链接时出现找不到符号的问题,需要注意提示信息中的符号是否有函数签名信息。如果有函数签名信息,则是依赖一个C++符号,否则就是依赖一个C符号。
场景还原
库代码:
// file: haha.c
int haha()
{
return 0;
}
生成动态库:
$ gcc -c haha.c
$ gcc -fPIC -shared haha.o -o libhaha.so
客户代码:
// file: main.cpp
int haha();
int main()
{
haha();
return 0;
}
编译并链接动态库:
$ g++ -c main.cpp
$ g++ main.o -L. -lhaha
/usr/bin/ld: main.o: in function `main':
main.cpp:(.text+0x9): undefined reference to `haha()'
collect2: error: ld returned 1 exit status
问题分析和解决
问题出在库中的符号为C符号,而引用的符号为C++符号,两者并不匹配。
符号如下:
$ nm libhaha.so | grep haha
00000000000010f9 T haha
$ nm main.o | grep haha
U _Z4hahav
解决办法就是将引用的符号调整为C符号,如下:
// file: main.cpp
extern "C"
{
int haha();
}
int main()
{
haha();
return 0;
}
重新编译后,符号一致,如下:
$ nm main.o | grep haha
U haha
链接器两个不同的表现
注意到,编译链接的时候的报错中的这一行:
main.cpp:(.text+0x9): undefined reference to `haha()'
报错直接给出了引用的函数签名(无参函数),这提示我们,链接的信息包含函数签名,这是C++符号的特征。
再做一个试验,观察在C中找不到一个符号的报错:
// file: main.c
int haha();
int main()
{
haha();
return 0;
}
// file: main.cpp
extern "C"
{
int haha();
}
int main()
{
haha();
return 0;
}
直接编译:
$ gcc -c main.c
$ gcc main.o
/usr/bin/ld: main.o: in function `main':
main.c:(.text+0xe): undefined reference to `haha'
collect2: error: ld returned 1 exit status
$ g++ -c main.cpp
$ g++ main.o
/usr/bin/ld: main.o: in function `main':
main.cpp:(.text+0x9): undefined reference to `haha'
collect2: error: ld returned 1 exit status
此时在提示的信息中没有函数签名,这提示我们找不到的符号是一个C符号。
标签:两种,符号,int,haha,cpp,main,链接 From: https://www.cnblogs.com/amazzzzzing/p/17153382.html