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

C++ 共享库libbar.so静态链接到libfoo.a,程序链接到libbar.so和libfoo.so,会发生什么?,c++,linker,global-variables,shared-libraries,static-libraries,C++,Linker,Global Variables,Shared Libraries,Static Libraries,(希望这不会变得太复杂…) 我已经构建了一个第三方C++库 LBFoO ,同时使用静态()和共享( LBoFo.S.)版本。对象文件是使用-fPIC创建的libfoo有几个用于配置其行为的全局变量,以及依赖这些全局变量的函数,为了简单起见,函数func1()与变量global\u a交互 我已经构建了我的C++共享库 LabBar ,我静态链接到 LBFoO。这是在没有--whole archive选项的情况下完成的。所以我相信libbar.So包含了它需要的libfoo.a中的所有符号和定义。

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

我已经构建了一个第三方C++库<代码> LBFoO ,同时使用静态()和共享( LBoFo.S.<代码>)版本。对象文件是使用-fPIC创建的

libfoo
有几个用于配置其行为的全局变量,以及依赖这些全局变量的函数,为了简单起见,函数
func1()
与变量
global\u a
交互

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

<>最后,我有一个C++客户端程序<代码> BAZ./COD>动态链接到<代码> libfo。所以和libBar。所以。此客户机还使用来自
libfoo
的相同函数/全局变量。它修改
global\u a
并调用
func1()

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

对于全局变量,我有点希望
libbar.so
中的代码会使用自己的副本,而
baz
中的任何更改都会修改
libfoo.so
中的副本,但这不是我看到的。当
baz
修改
global_a
时,效果可以在
libbar.so
中看到。客户
baz
没有任何其他异常行为,我看不出来

我还尝试将
baz
链接到
libfoo.a
,并看到了相同的(显然是正确的)行为

Valgrind在这两种情况下均未显示任何错误

一般来说,在这个场景中,客户端baz的行为是什么

通常,UNIX/ELF系统上共享库的行为旨在模仿归档库的行为

特别是,如果您的二进制
baz
链接到
libfoo.so
libbar.so
,两者都导出
global\u a
,则第一个定义获胜。也就是说,来自
baz
libfoo.so
libbar.so
的所有对
global_a
的引用都将绑定到链接顺序中找到的第一个实例(这里大概是
libfoo.so

可以通过隐藏符号来修改此行为,例如使用
-fvisibility hidden
、使用
\uuuu属性((可见性(“隐藏”))
或使用链接器脚本

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

nm -AD libfoo.so libbar.so | grep global_a
(此命令将仅显示导出的符号)

对于全局变量,我希望libbar.so中的代码使用自己的副本

这种期望是不正确的

这种配置是我应该避免的,还是可以

这是您通常应该避免的,因为例如更新
libbar.so
而不重新链接
libfoo.so
可能会产生不一致性。假设
global\u a
的类型在以后的版本中从
int
更改为
double
。突然间,一个简单的陈述如下:

global_a = 0.0;
内部
libbar.so
现在可能会损坏
global\u a
内部
libfoo.so
(内部
libfoo.so
中的
global\u a
仍然是一个4字节
int
,但现在得到写入其中的8字节
double

Valgrind在这两种情况下都没有显示错误


Valgrind在检查globals方面异常薄弱,几乎从不抱怨。你应该养成用gcc-fsanize=address检查程序的习惯。

谢谢,这非常有用。你有什么参考资料可以让我读到类似的东西吗?至于
-fsanizize
,不幸的是我被GCC4.4.7(Centos 6)卡住了,所以我无法使用它。