我有一个链接问题。 我需要链接到共享库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是一个共享库吗?
首先,定义一个名为“read”的函数是一个坏主意(TM),因为它是所有UNIXen上的标准libc函数。 当你这样做时,你的程序的行为是不确定的。
其次,在libbaz.so
定义的read
函数在nm
输出中标记为't'
。 这意味着这个函数是本地的(在libbaz.so
之外不可见)。 全局函数以'T'
nm
'T'
标记。
当你在read.c中定义它时,你使用了'static int read(...)'
吗? 如果没有,当编译和链接libbaz.so
时,是否使用链接描述文件或attribute((visibility(hidden)))
,或者-fvisibility=hidden
命令行?
当C代码用G ++编译,然后链接时,上述错误也会发生。 G ++执行名称修改,因此实际的符号可能类似于“_Zsds_ [function_name] _”,导致链接器在搜索未被修改的名称时阻塞。
今天我遇到了同样的行为,除了我的问题是在维基百科上列出的行动之后解决的。 基本上,用C ++编译器编译的C代码在符号表中会有一个“错位”的名字,导致C风格的符号解析失败。
在构建共享库时,需要从同一个库或另一个(共享)库中解析所有未定义的符号。 链接器不会从您的应用程序的符号库中解析未定义的符号。