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

时间:2016-09-30 20:21:15

标签: c++ linux dll

用C ++编写:

静态库" A"定义全局变量foo。

" B"和" C"两个动态库都依赖于A,因此(静态地)与A链接。

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

如果我们在windows环境中,我们将获得两个不同的foo实例,一个在B中,一个在C中,如下所述:

Shared global variable in C++ static library

Linux环境怎么样?

上下文: 我们目前正在将一个Windows项目移植到linux

1 个答案:

答案 0 :(得分: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 :默认符号可见性规则。   Globa和弱符号可供其他人使用   模块;本地模块中的引用可以   被其他人的定义所插入   模块。

关于SysV ABI

  

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

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

相比之下,在Windows上,始终从给定的DLL导入符号,并且默认情况下,符号不会导出到其他DLL。