乙個關於動態鏈結的問題

2021-06-26 06:08:51 字數 1851 閱讀 7173

碰到乙個動態鏈結的問題,下面是原始碼hello.h,hello.cpp,apis.h和main.cpp以及makefile。

hello.h,hello.cpp,apis.h生成動態鏈結庫libhello.so,main.cpp動態鏈結libhello.so。

在hello.cpp中定義了乙個全域性變數data,並且在hello類的建構函式中給data新增了資料,然後在apis.h中定義了hello的乙個例項和乙個api

#pragma once

class hello

;#include "hello.h"

#include #include std::vectordata;

std::vector*pdata;

hello::hello()

#include "hello.h"

#include #include extern std::vectordata;

extern std::vector* pdata;

hello h;

void test()

#include #include using namespace std;

void test();

extern vectordata;

extern vector* pdata;

int main()

#makefile

a.out: libhello.so main.cpp

g++ main.cpp ./libhello.so -o a.out

libhello.so: hello.cpp apis.cpp hello.h

g++ apis.cpp hello.cpp -fpic -shared -o libhello.so #1

#g++ hello.cpp apis.cpp -fpic -shared -o libhello.so #2

clean : rm libhello.so a.out

現在問題出現了:

使用makefile中的指令#1處時,得到的結果如下,也就是說變數data.size()的結果為0,而pdata->size()的結果為2

使用makefile中的指令#2處時,得到的結果如下,也就是說變數data.size()的結果為2,而pdata->size()的結果為2

在《程式設計師的自我修養》一書的7.3.4中專門介紹了共享模組全域性變數的問題(注:以下內容引述自該小節內容以)

當乙個模組引用了乙個定義在共享物件的全域性變數時,無法根據上下文判斷該變數是定義在共享模組內部還是其他模組。因為程式主模組也可能引用該全域性變數且程式的主模組**不是pic(位址無關**),故該變數的位址在鏈結過程中確定下來,在可執行檔案的.bss段中建立了乙個副本。編譯器的解決方案是所有使用該變數的指令都指向可執行檔案中的那個副本,且elf共享庫在編譯時預設把定義在模組內部的全域性變數當做定義在其他模組的全域性變數,通過got來實現變數的訪問,這樣變數在執行時始終只有乙個例項,如果變數在共享模組中被初始化,那麼動態鏈結器還需要將初始化值複製到程式主模組中的變數副本。

回到我的問題上,猜測兩種編譯方式導致不同結果的原因可能是因為模組編譯順序的不同導致沒有正確的初始化data變數。至於為什麼會這樣,需要檢視編譯出來模組的初始化**了。

乙個關於 include的問題

2001年05月03日 12 04 00 乙個關於 include的問題 趙湘寧 問題 我試圖將乙個標頭檔案包含在工程的資源檔案中。為此在.rc檔案中新增了如下一行 include myfile.h 雖然執行沒有問題,但是每次在visual studio中開啟資源時,它都把這一行 刪除掉了。我之所以...

關於繼承的乙個問題

class a virtual a class b public a virtual b class c public b virtual c int fun int n char last4hex unsigned int num,char a 5 int main int argc,char a...

乙個關於授權的問題

grant all on ibench.to ibench 增加乙個使用者 ibench,該使用者擁有對資料庫 ibench 的所有許可權.等價於以下的寫法 grant all privileges on ibench.to ibench 如果不好用需要如下操作 4.0以前的似乎flush priv...