[编辑:简而言之,问题是:当我链接到一个链接到另一个动态库的动态库时,我是否也必须显式链接该动态库?]
我在一个软件中看到了类似的东西。它不起作用,现在我想知道它是否应该起作用。我可以将一个库“bar”动态链接到另一个库“foo”,然后链接到该库以访问“foo”中的符号(因为“bar”应该链接到“foo”)吗? (我正在使用 linux 和 gcc 4.8.2,以防万一。)
具体假设我有以下三个文件。现在我做到了
gcc -c -Wall -Werror -fpic foo.c
gcc -shared -olibfoo.so foo.o
我通常会在什么时候做
gcc -o program main.c -L. -lfoo
获得一个工作程序。现在我这样做了
gcc -shared -olibbar.so -L. -lfoo
gcc -o program main.c -L. -lbar
这不起作用:
/tmp/cciNSTyI.o: In function `main':
main.c:(.text+0xf): undefined reference to `foo'
collect2: error: ld returned 1 exit status
应该吗?
foo.h
#ifndef foo_h__
#define foo_h__
extern void foo(void);
#endif
foo.c
#include <stdio.h>
void foo(void)
{
puts("foo");
}
main.c
#include <stdio.h>
#include "foo.h"
int main(void)
{
puts("Library test...");
foo();
return 0;
}
编辑:我写了一个关于我对下面发生的事情的理解的答案。
我仍然不太清楚的一件事是参数的顺序:如果(使用该答案中的文件 bar.c)我将 bar 与行链接(注意“bar.o”的位置)
gcc -o program main.c -L. -lbar
gcc -shared -olibbar.so -L. -lfoo bar.o
那么它“bar”不依赖于“foo”:
> readelf -d libbar.so
Dynamic section at offset 0xe18 contains 24 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x5a8
[...]
最佳答案
不,不可能“转发”动态链接库。
当您静态或动态链接任何库时,您实际上使主可执行文件能够调用链接库中定义的函数/符号。
就您而言,图书馆 bar
,没有函数foo()
其中定义的。那么当 bar.so
创建后,生成的符号将注册在主可执行文件的符号表中 - program
。如bar
中的符号lib 不包含任何名为 foo()
的函数,它没有注册到 program
的符号表中。那么当 foo()
在一段时间内被调用,加载程序尝试查找其中 foo()
的 .so将在编译期间链接的所有库中定义 program
。因此出现运行时错误。它不会显示编译时错误,因为您已包含 foo.h
其头文件。
您需要显式链接所有要在正在编译的代码中引用的符号(函数、变量、常量等)的库。
关于c - 动态库 "forwarding",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28961624/