《程式設計師自我修養》觀後驗證第二彈。
第乙個例子:
有三個程式:
main.cpp
#include int global_symbol = 300;
extern void testso1();
extern void testso2();
int main()
so1.cpp
#include int global_symbol = 500;
void testso1()
so2.cpp
#include int global_symbol = 900;
void testso2()
編譯的命令:
g++ -fpic -c so1.cpp
g++ -fpic -c so2.cpp
g++ -c main.cpp
g++ -shared -o so1.so so1.o
g++ -shared -o so2.so so2.o
g++ main.o so1.so so2.so
輸出的結果是:
the value of global symbol is 301
the value of global symbol in so1 is 302
the value of global symbol is 303
the value of global symbol in so2 is 304
the value of global symbol is 305
原因:
a. 共享物件在編譯時不能假設自己在程序虛擬位址空間中的位置。
b. 共享庫在編譯時,預設都把定義在模組內部的全域性變數,當做定義在其他模組的全域性變數。
c. 當共享模組被裝載時,如果某個全域性變數在可執行程式中擁有副本,那麼動態鏈結器(在我的測試環境是/lib64/ld-linux-x86-64.so.2)就會把全域性偏移表(got global offset table)中的相應位址指向該副本,這樣該變數在執行時實際上最終就只有乙個例項。如果變數在共享庫中被初始化,動態鏈結器還要將該初始化值複製到程式主模組中的變數副本;如果該全域性變數在程式主模組中沒有副本,那麼got的相應位址就指向模組內部的該變數副本。(第二個例子驗證)
得到的經驗:
在動態庫宣告和操作全域性變數的時候,不能認為在共享庫的初始化的值,就是這個全域性物件的真正初始值。
第二個例子:
將main.cpp中的 int global_symbol = 300; 改為extern int global_symbol; (即只做宣告)
則輸出的結果取決於鏈結的順序。
如果鏈結的命令是
g++ main.o so1.so so2.so
則輸出為:
the value of global symbol is 501
the value of global symbol in so1 is 502
the value of global symbol is 503
the value of global symbol in so2 is 504
the value of global symbol is 505
如果鏈結的命令是
g++ main.o so2.so so1.so
則輸出為:
the value of global symbol is 901
the value of global symbol in so1 is 902
the value of global symbol is 903
the value of global symbol in so2 is 904
the value of global symbol is 905
動態庫中,關於全域性變數的呼叫
測試目的 動態庫中全域性變數的使用方法 測試結果 主程式和庫b共用一套a的動態庫,共用一套全域性變數。庫a的 includeint pri 0 void fun void change 編譯 gcc shared sa.c o libsa.so 庫b的 include includevoid fun...
關於 全域性變數
全域性變數一般這樣定義 1。在一類的.cpp中定義 int myint 然後再在要用到的地方的.cpp裡extern int myint 這樣就可以用了。2。在stdafx.cpp中加入 int myint 然後在stdafx.h中加入 extern int myint 這樣定義以後無論在什麼檔案中...
python中關於全域性變數
title date br python中關於全域性變數 2019 09 03 15 58 02 0700 python基礎 python num 1 定義全域性變數 def test1 num 2 print num def test2 print num test1 test2 2 1 並未如所...