2016-09-30 74 views
2

This in in C++:C++静态库中的共享全局变量:Linux

静态库“A”定义了一个全局变量foo。

“B”和“C”是两个动态库既取决于因此联(静态地)与A.

然后B和C最终装在同一进程 (例如:加载应用程序B和C)。

如果我们在Windows环境中,我们将获得富的两个不同的实例,一个在B和一个用C这里清楚地解释:

Shared global variable in C++ static library

什么Linux环境。

语境: 目前,我们正在移植Windows项目到Linux

+0

如果你不能得到答案我想你可以通过改变1库中的全局变量并从第二个库检查它的值来执行一个简单的测试。 –

回答

1

每个图书馆将推出包括A的副本,但是,在运行时只有一个会通过过程的所有组件使用。

// h.h 
extern int a; 
void b(void); 
void c(void); 

// a.c 
#include "h.h" 
int a = 0; 

// b.c 
#include <stdio.h> 
#include "h.h" 
void b(void) 
{ 
    printf("%i\n", a++); 
} 

// c.c 
#include <stdio.h> 
#include "h.h" 
void c(void) 
{ 
    printf("%i\n", a++); 
} 

//main.c 
#include <stdio.h> 
#include "h.h" 
int main() 
{ 
    b(); 
    c(); 
} 

#Makefile 
main: libxc.so libxb.so 
    cc -o main main.c -L. -lxc -lxb 
libxb.so: 
    cc -fPIC -shared a.c b.c -o libxb.so 
libxc.so: 
    cc -fPIC -shared a.c c.c -o libxc.so 
$make 
$ LD_LIBRARY_PATH=. ./main 
0 
1 
libxa.so

符号表:

 
    53: 000000000020098c  4 OBJECT GLOBAL DEFAULT 24 a 

libxc.so

 
    53: 000000000020098c  4 OBJECT GLOBAL DEFAULT 24 a 

默认能见度STV_DEFAULT其中根据LSB

STV_DEFAULT:符号与STV_DEFAULT 属性能见度如由符号的绑定类型指定。也就是说, 全局和弱符号在它们的 之外是可见的,定义了 组件(可执行文件或共享对象)。如下所述,本地符号为隐藏的 。全局符号和弱符号也都是 可抢占的,也就是说,它们可能被同一个 名称在另一个组件中的定义抢先。

man 5 elf

STV_DEFAULT:默认符号可见性规则。 其他 模块可以使用全局符号和弱符号;本地模块中的引用可以通过其他 模块中的定义插入到 中。

关于SysV ABI

当解析符号引用时, 动态连接器检查与广度优先搜索的符号表。 也就是说,它首先查看可执行程序 程序本身的符号表,然后在 DT_NEEDED条目的符号表(按顺序),然​​后在第二级DT_ NEEDED 条目等等。

如果这不符合预期,则在符号上使用STV_HIDDEN可防止它在共享对象外部可见。

相比之下,在Windows上,一个符号总是从给定的DLL中导入,并且这些符号默认情况下不会导出到其他DLL。