共享库中的c ++静态变量和更好的可见性

时间:2018-06-14 01:52:50

标签: c++ static shared-libraries

共享库A包含静态数据S,A共享链接共享库B和共享库C.主进程将在运行时动态加载B.so和C.so。在测试期间,看起来像数据S在B和C之间共享。但我不知道为什么。

我的第一个问题是:我了解到共享的lib代码是共享的(内存中只有一个文本副本),是否意味着如果多个lib使用共享库中的数据应该重复?比如静态数据S.

第二个问题是:目前我将数据S声明为

struct S {
    static S1 s1;
    static S2 s2;
    ...
}
在A.h文件中

并在A.cpp文件中定义它们。对于阅读此代码的人来说,获得这些静态数据是共享的而不是不同的编译单元将拥有自己的副本可能并不明显。是否有一种体面的方式让它更明显?

谢谢!

1 个答案:

答案 0 :(得分:0)

首先,请注意在Windows上通常的情况是动态库不共享变量,只共享函数。但Unix模型是任何链接都具有相同的语义:每个模块的所有依赖项都被加载,但在客户端中不包含 ,因为这可能会导致重复。

这通常被认为是一个特性:如果您的库具有全局状态(例如,以保护共享资源,如配置文件),那么在所有情况下都可以拥有一个(每个进程) 。至于“显而易见”,你通常应该假设你的客户知道这一点(他们需要了解你库中的全局变量)。

当然,更好的想法是避免这种全局状态:而是让客户端维护它(当然,使用库提供的功能)。一些这样的共享状态自然地变成了一些附近堆栈帧的本地状态,起到了类似于Builder模式的作用。其他的可以是线程本地的(可能只是在线程的初始函数中是本地的)。

实际上需要在整个流程范围内的任何内容最终都会成为main中的本地内容,而将其余代码转换为无状态,可组合的库。 (这些变量可能在包含static的翻译单元中为main而不是其他,但这只是限制了它们的初始化。)