2009-06-03 65 views
2

我遇到链接问题。我需要链接到共享库libfoo.so,这取决于函数read,我想在read.c文件中定义自己。nm报告符号已定义,但ldd报告符号未定义

我编译和链接在一起的一切,但在运行时出现错误

/home/bar/src/libfoo.so: undefined symbol: sread. 

纳米报告符号被定义

$nm baz | grep sread 
    00000000000022f8 t sread 

但LDD报告symbol未定义

$ldd -r baz | grep sread 
undefined symbol: sread (/home/bar/src/libfoo.so) 

什么给了? libfoo.so是一个共享库吗?

+0

也许你应该发布所有共享对象和可执行文件的完整链接线,以阐明这个主题。 – lothar 2009-06-03 05:46:08

回答

13

首先,定义一个名为'read'的函数是一个坏主意(TM),因为它是所有UNIXen上的标准libc函数。当你这样做时,你的程序的行为是不确定的。

其次,您在libbaz.so中定义的read函数在nm输出中标有't'。这意味着这个功能是本地的(libbaz.so以外不可见)。全球功能用'T'nm标记。

当您在read.c中定义它时,是否使用了'static int read(...)'? 如果不是,那么在编译和链接libbaz.so时,是否在命令行上使用链接描述文件或attribute((visibility(hidden)))-fvisibility=hidden

-1

当您构建共享库时,您需要从同一个库或另一个(共享)库中解析未定义的符号全部。链接器将而不是从您的应用程序的符号库中解析未定义的符号。

+0

我应该说明baz实际上是一个共享库。那么这是否意味着我应该创建一个仅包含读取函数的共享库,并链接到这个库?有没有一种明确的方式告诉链接器使用这个其他共享库(比如说libread.so)来解析来自共享库libfoo.so的未定义符号? – codehippo 2009-06-03 04:16:09

+2

你完全搞错了:运行时加载程序会高兴地从共享库中解析未定义的符号,只要符号在其动态表中被“导出”(这发生在例如当可执行文件与-rdynamic链接时) 。 – 2009-06-03 05:06:29

1

当使用G ++编译C代码,然后进行链接时,上述错误也会发生。 G ++执行名称修改,因此实际符号可能与“_Zsds_ [function_name] _”类似,导致链接器在搜索未被修改的名称时会窒息。

今天我遇到了相同的行为,除了我的问题在Wikipedia上列出的操作后解决。基本上,用C++编译器编译的C代码在符号表中会有一个“错位”的名称,导致C样式符号解析失败。