我有一个共享对象/可执行文件,它可以静态和动态地链接到同一个库。
图书馆:liba.a和liba.so
使用以下命令创建liba.a :ar -rv liba.a a.o, 包含 libprint() - >打印“static5”
使用以下命令创建liba.so :gcc -shared -o liba.so -Wl,-h,liba.so ao,包含 libprint()打印“dynamic5” , libprint2()打印“dynamic6”
通过链接到存档和共享对象创建的 b :
当与GCC / Linux链接时,我发现调用的实现始终来自liba.a。 击>
我在liba.so,liba.a中定义了一个函数 libprint(),它打印出一个不同的值。 从我看到的,这是基于链接顺序:
gcc -o b b.o liba.a liba.so -lc ./b
static5 dynamic6
gcc -o b b.o 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 =&gt; ./liba.sob 链接到共享对象 libd.so 并归档 liba.a 。
gcc -o b b.o libd.so liba.a -lc ldd b libd.so =&gt; ./libd.so liba.so =&gt; ./liba.so
现在, b 似乎首先从归档调用该函数,然后是共享对象。
因此,即使我们更新 liba.so ,这些更改也不会反映在 b 中。 有没有办法解决 ?
答案 0 :(得分:1)
当您首先放置.a时,链接器会在其中找到libprint()
并链接它,但不会链接libprint2()
。它继续搜索库以便找到其他函数,并在.so。
当您首先放置.so时,会找到并成功链接这两个函数,因此无需再查找它们。
没有理由将两个链接到同一个库的静态和动态版本,因为它们应该提供在另一个库中找到的所有函数。