2011-06-06 100 views
2

我有一个静态和动态链接到同一个库的共享对象/可执行文件。静态和动态链接Linux上的同一个库

库:liba.a和liba.so

liba.a使用创建的:AR -rv liba.a AO, 包含libprint() - >打印“static5 “

liba.so使用创建的:GCC -shared -o liba.so -Wl,-h,liba.so AO,包含libprint()打印 ”dynamic5“ libprint2()打印 “dynamic6”

埃克b通过链接到两个归档创建和共享对象:

当与GCC/Linux的连接,我发现,称为实施始终来自liba.a。

我有一个函数libprint()定义在liba.so中,liba.a打印出一个不同的值。 从我看到的,这是基于连接顺序:

GCC -Ob博liba.a liba.so -lc ./b

static5 dynamic6

GCC -Ob博liba.so liba.a -lc ./b

dynamic5 dynamic6

为什么我们故意需要链接到同一个库的.a和.so:

我们如何让共享对象优先于归档而不是链接顺序? (-dy/-Bdynamic似乎并没有产生什么影响?)

1.如果共享对象丢失,这个exe因错误而失败 2.我们可以放置任何具有相同名称的虚拟共享对象,只是为了满足dlopen() 3。即使一旦共享对象被加载,从归档的函数被调用

更新#2 这里是(如在Statically and dynamically linking the same library提到的)的实际问题

libd.so链接到共享对象liba.so
ldd libd.so liba.so => ./liba.so

b被链接到共享对象libd.so和归档liba.a

GCC -ob博libd.so liba.a -lc LDD b libd.so => ./libd.so liba.so => ./liba.so

现在,b似乎首先从存档调用函数,然后是共享对象。

所以,即使我们更新liba.so,这些变化不会反映在b。 有没有办法解决这个问题?

+0

可能要添加/搜索标签gcc。祝你好运。 – shellter 2011-06-06 03:28:20

回答

1

当您首先插入.a时,链接器会在其中找到libprint()并链接它,但不链接到libprint2()。它继续搜索库以查找其他函数,并在.so中找到它。

当你把.so放到第一位时,两个函数都被找到并成功链接,因此不需要再进一步查找它们。

应该没有理由链接两个同一个库的静态和动态版本,因为任一个都应该提供在另一个库中找到的所有函数。

+0

谢谢@ ignacio-vazquez-abrams。 我有一个链接到.a和.so的可执行文件。我试图找出可能的原因。 问题是,我们可以更新共享对象,但它似乎没有被调用,因为可执行文件仍然使用原始存档中的函数。 – TTA 2011-06-06 07:10:24

+0

.a文件[在构建时链接](http://stackoverflow.com/questions/2246799/static-library-dynamic-library-confusion/2246911#2246911)。 – 2011-06-06 07:17:43

+0

我已更新与实际案件的问题。 共享目标文件首先在链接行中,但是,实际功能存在于链接的so文件中,而不是实际的。 这仍然会导致存档版本被拿起。 – TTA 2011-06-06 08:15:46