1. 程式人生 > >Linux靜態連結庫、動態連結庫、動態載入庫

Linux靜態連結庫、動態連結庫、動態載入庫

所謂靜態連結庫,說白了就是在你把寫好的程式碼編譯的時候,就把你引用的庫一起給編進去了,從此後你編出來的執行程式跟外面都不再有任何關係,即使這個庫更新了,你也搭不上邊兒,其次,如果系統中許多類似的程式都需要用到這個庫,那麼各自在編譯的時候都需要把這個庫給編進去,浪費儲存空間(載入到記憶體裡應該也是浪費記憶體空間的)。linux系統中靜態庫的名字一般叫xxx.a, 所以如果你看到一個以 .a結束的檔案那麼它多半就是一個靜態連結庫利用靜態連結庫編譯成的檔案比較大,因為整個函式庫的所有資料都被整合進目的碼中

所謂動態連結庫,也就是說編譯的時候不會真的把你引用到的庫給編到你的執行程式裡(編譯的時候只會留下庫函式的位置資訊),而是在程式啟動的時候才會去載入相關的庫,所有用到此庫的程式可以共享一份程式碼,這樣帶來的好處是可執行程式所佔的空間變小了,同時,如果庫需要升級,你並不需要重新編譯你的程式,只要把相關的庫升級即可。


    動態連結庫有利於程序間資源共享:什麼概念呢?就是說,某個程式在執行中要呼叫某個動態連結庫函式的時候,作業系統首先會檢視所有正在執行的程式,看在記憶體裡是否已有此庫函式的拷貝了。如果有,則讓其共享那一個拷貝;只有沒有時才連結載入。這樣的模式雖然會帶來一些“動態連結”額外的開銷,卻大大的節省了系統的記憶體資源。C的標準庫就是動態連結庫,也就是說系統中所有執行的程式共享著同一個C標準庫的程式碼段。而靜態連結庫則不同,如果系統中多個程式都要呼叫某個靜態連結庫函式時,則每個程式都要將這個庫函式拷貝到自己的程式碼段,顯然將佔有更大的記憶體資源。

共享庫,有兩種形式,第一種就是在上一篇文章中說到的“動態連結庫”,而共享庫的另一種形式,則被稱之為“

動態載入庫”,也就是我剛才提到的用“dlopen”方式來玩的。動態載入庫在編譯的時候,應該是不需要去-l引用lib,而是在可執行程式中,可以自已決定載入庫的時機。比如程式跑著跑著,突然想用libabc.so庫裡的一個叫abc的函數了,這時就可以用dlopen去開啟這個庫,然後使用dlsym去找到abc的函式指標並呼叫即可。

總結:動態連結庫在載入時機是程序啟動,而動態載入庫則由程式自行決定載入時機。