歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

C語言之靜態鏈接庫和動態鏈接庫

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指定動態庫的地址。

Copyright © Linux教程網 All Rights Reserved