1:靜态連結庫
比較早出現的是靜态連結庫。靜态庫其實就是商業公司将自己的函數庫源代碼經過隻編譯不連接配接形成.o的目标檔案,然後用ar工具将.o檔案歸檔成.a的歸檔檔案(.a的歸檔檔案又叫靜态連結庫檔案)。商業公司通過釋出.a庫檔案和.h頭檔案來提供靜态庫給客戶使用;客戶拿到.a和.h檔案後,通過.h頭檔案得知庫中的庫函數的原型,然後在自己的.c檔案中直接調用這些庫檔案,在連接配接的時候連結器會去.a檔案中拿出被調用的那個函數的編譯後的.o二進制代碼段連結進去形成最終的可執行程式。
2:動态連結庫
動态連結庫比靜态連結庫出現的晚一些,效率更高一些,是改進型的。現在我們一般都是使用動态庫。靜态庫在使用者連結自己的可執行程式時就已經把調用的庫中的函數的代碼段連結進最終可執行程式中了,這樣好處是可以執行,壞處是太占地方了。尤其是有多個應用程式都使用了這個庫函數時,實際上在多個應用程式最後生成的可執行程式中都各自有一份這個庫函數的代碼段。當這些應用程式同時在記憶體中運作時,實際上在記憶體中有多個這個庫函數的代碼段,這完全重複了。而動态連結庫本身不将庫函數的代碼段連結入可執行程式,隻是做個标記。然後當應用程式在記憶體中執行時,運作時環境發現它調用了一個動态庫中的庫函數時,會去加載這個動态庫到記憶體中,然後以後不管有多少個應用程式去調用這個庫中的函數都會跳轉到第一次加載的地方去執行(不會重複加載)
3:靜态連結庫和動态連結庫的比較
靜态庫是使用者在連結位元組的可執行程式時已經将調用到的庫函數的代碼段連結到最終的可執行程式中,這樣的好處是這樣的可執行檔案放到任何地方都能執行,壞處是庫函數很占地方,使得連結得到的最終的可執行程式變得很大。
使用動态庫的時候,函數本身編譯連結到得到可執行程式的時候,并不會講庫函數連結到可執行程式中去,而是标記這個函數用到哪些庫函數,當這個可執行程式運作時,作業系統會自動加載這些庫到記憶體中。
比較:
通過上面的分析可以知道,靜态庫是将庫函數連結到最終的可執行程式中,而動态庫是沒有将庫函數連結到可執行程式中。從單個可執行程式的角度出發可執行程式在記憶體中運作時,系統還是會将庫函數加載到記憶體中,這樣從記憶體角度上講,兩個可執行程式最終在記憶體中運作時所占的空間還是一樣的。但是從多個程式出發,就不一樣了,比如a程式和b程式都用到了printf函數,使用靜态庫時,這兩個可執行程式都包含了printf函數,是以這時候記憶體中就包含了兩份printf函數;而使用動态庫的時候,系統隻會加載一份printf函數,當其他函數也要用到printf函數時,隻要到加載的printf函數的位址中調用即可,不需要再次加載,是以當多個程式運作時,靜态庫就明顯比動态庫更占記憶體。
4:函數庫中庫函數的使用
(1)gcc中編譯連結程式預設是使用動态庫的,要想靜态連結需要顯式用-static來強制靜态連結。
(2)庫函數的使用需要注意3點:第一,包含相應的頭檔案;第二,調用庫函數時注意函數原型;第三,有些庫函數連結時需要額外用-lxxx來指定連結;第四,如果是動态庫,要注意-L指定動态庫的位址。
本文轉自 菜鳥養成記 51CTO部落格,原文連結:http://blog.51cto.com/11674570/1863612