我遇到了链接问题。我需要链接一个依赖于函数libfoo.so
的共享库read
,我想在read.c文件中定义它。
我编译并将所有内容链接在一起,但在运行时我收到错误
/home/bar/src/libfoo.so: undefined symbol: sread.
nm报告符号已定义
$nm baz | grep sread
00000000000022f8 t sread
但ldd报告符号未定义
$ldd -r baz | grep sread
undefined symbol: sread (/home/bar/src/libfoo.so)
是什么给出的?是否存在libfoo.so是共享库的事实?
答案 0 :(得分:13)
首先,定义一个名为'read'的函数是一个坏主意(TM),因为它是所有UNIXen上的标准libc函数。执行此操作时,程序的行为是不确定的。
其次,您在read
中定义的libbaz.so
功能在't'
输出中标有nm
。这意味着此函数是本地的(在libbaz.so
之外不可见)。全局函数的标记为'T'
nm
。
在read.c中定义它时是否使用了'static int read(...)'
?
如果没有,在编译和链接attribute((visibility(hidden)))
时,您是否在命令行上使用了链接描述文件,-fvisibility=hidden
或libbaz.so
?
答案 1 :(得分:1)
使用G ++编译C代码然后链接时,也会发生上述错误。 G ++执行名称修改,因此实际符号可能类似于“_Zsds_ [function_name] _”,导致链接器在搜索未损坏的名称时会发生阻塞。
我今天遇到了同样的行为,但我的问题在Wikipedia上列出的行动后得到了解决。基本上,使用C ++编译器编译的C代码在符号表中会有一个“损坏”的名称,导致C风格的符号解析失败。
答案 2 :(得分:-1)
构建共享库时,需要从同一个库或另一个(共享)库中解析所有未定义的符号。链接器不使用应用程序中的符号从库中解析未定义的符号。