链接找不到符号的两种表现
链接找不到符号的两种表现
本文分析链接时找不到符号时的两个不同表现,帮助快速定位问题。
结论
如果链接时出现找不到符号的问题,需要注意提示信息中的符号是否有函数签名信息。如果有函数签名信息,则是依赖一个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符号。
posted on 2023-02-24 22:14 amazzzzzing 阅读(408) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)