gpt4 book ai didi

c++ - 共享库 libbar.so 静态链接到 libfoo.a,程序链接到 libbar.so 和 libfoo.so,会发生什么?

转载 作者:行者123 更新时间:2023-11-30 05:38:37 25 4
gpt4 key购买 nike

(希望这不会变得太复杂...)

我构建了一个第三方 C++ 库 libfoo具有静态(libfoo.a)和共享(libfoo.so)版本。目标文件是使用 -fPIC 创建的。 libfoo有几个用于配置其行为的全局变量,以及依赖这些全局变量的函数,为简单起见函数 func1()它与变量 global_a 交互.

我已经构建了我的 C++ 共享库 libbar我已经静态链接到 libfoo.a .这是在没有 --whole-archive 选项的情况下完成的。所以我相信libbar.so包括它需要的所有符号和定义,来自 libfoo.a .该库从 libfoo 调用函数它使用全局变量来控制行为。在这种情况下,假设它调用函数 func1() .

终于有了一个C++客户端程序baz动态链接到 libfoo.solibbar.so .此客户端还使用来自 libfoo 的相同函数/全局变量.它修改了 global_a并调用 func1() .

一般来说,客户端的行为是什么baz在这种情况下?这种配置是我应该避免的,还是可以的?如果 libfoo.a 会发生什么?和 libfoo.so是不同的版本吗?

对于全局变量,我有点期待 libbar.so 中的代码将使用自己的拷贝,以及 baz 中的任何更改将修改 libfoo.so 中的拷贝,但这不是我所看到的。当baz修改 global_a ,效果见libbar.so .客户端baz没有任何其他异常行为我看得出来。

我也试过链接 bazlibfoo.a ,并看到相同的(显然是正确的)行为。

无论哪种情况,Valgrind 都没有显示任何错误。

最佳答案

In general, what will be the behavior of the client baz in this scenario?

一般,共享库在 UNIX/ELF 系统上的行为旨在模仿存档库的行为。

特别是,如果您的二进制 baz 链接到 libfoo.solibbar.so,两者都export global_a,则第一个定义获胜。也就是说,bazlibfoo.solibbar.soglobal_a 的所有引用都将绑定(bind)到第一个在链接顺序中找到的实例(这里大概是 libfoo.so)。

可以通过使用例如隐藏符号来修改此行为。 -fvisibility-hidden,使用 __attribute__((visibility("hidden"))) 或使用链接器脚本。

您可以查看每个库导出的内容

nm -AD libfoo.so libbar.so | grep global_a

(此命令只会显示导出的符号)。

For the global variables I was sort of expecting that the code in libbar.so would use its own copies

这种期望是不正确的。

Is this sort of configuration something I should avoid, or is it OK?

这是您通常应该避免的事情,因为例如在不重新链接 libfoo.so 的情况下更新 libbar.so 可能会产生不一致。假设 global_a 的类型在以后的修订版中从 int 更改为 double。突然间有一个简单的语句,例如:

global_a = 0.0;

inside libbar.so 现在可能会损坏 libfoo.soglobal_a 之后的无关变量(global_alibfoo.so 中仍然是一个 4 字节的 int,但现在写入了 8 字节的 double

Valgrind in either case has no shown errors.

Valgrind 在检查全局变量方面异常薄弱,而且几乎从不提示它们。您应该养成使用 gcc -fsanitize=address 检查程序的习惯。

关于c++ - 共享库 libbar.so 静态链接到 libfoo.a,程序链接到 libbar.so 和 libfoo.so,会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32642234/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com