2016-09-30 289 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。