連接庫是windows的術語,但對於Linux來講,其概念是同樣的。咱們一般會把一些類似或相近功能的程序生成連接庫,這樣的好處是:windows
1)便於共享,開發軟件時如須要相同功能時,不須要將大量重複的代碼整合到工程當中,直接調用便可。模塊化
2)便於保密,連接庫是二進制的,源代碼是不可見的。函數
連接庫有動態與靜態兩種,Linux動態庫一般用.so爲後綴,靜態庫用.a爲後綴。性能
(1)靜態連接,在這種連接方式下,函數代碼將從其所在的靜態連接庫中拷貝到最終的可執行程序中。這樣該程序在被執行時這些代碼將被裝入到該進程的虛擬地址空間中。靜態連接庫其實是一個目標文件的集合,其中的每一個文件含有庫中的一個或者一組相關函數的代碼。spa
(2)動態連接,在此種方式下,函數的代碼被放到稱做是動態連接庫或共享對象的某個目標文件中。連接程序此時所做的只是在最終的可執行程序中記錄下共享對象的 名字以及其它少許的登記信息。在此可執行文件被執行時,動態連接庫的所有內容將被映射到運行時相應進程的虛地址空間。動態連接程序將根據可執行程序中記錄的信息找到相應的函數代碼。對象
對於可執行文件中的函數調用,可分別採用動態連接或靜態連接的方法。使用動態連接可以使最終的可執行文件比較短小,而且當共享對象被多個進程使用時能節約一些內存,由於在內存中只須要保存一份此共享對象的代碼。但並非使用動態連接就必定比使用靜態連接要優越。在某些狀況下動態連接可能帶來一些性能上的損害。進程
靜態庫和動態庫的區別內存
1.利用靜態函數庫編譯成的文件比較大,由於整個函數庫的數據會被整合進目標代碼中,他的優勢就顯而易見了,即編譯後的執行程序不須要外部的函數庫支持,由於全部使用的函數都已經被編譯進去了。固然這也會成爲他的缺點,由於若是靜態函數庫改變了,那麼你的程序必須從新編譯。資源
2.相對於靜態函數庫,動態函數庫在編譯的時候並無被編譯進目標代碼中,你的程序執行到相關函數時才調用該函數庫裏的相應函數,所以動態函數庫所產生的可執行文件比較小。因爲函數庫沒有被整合進你的程序,而是程序運行時動態的申請並調用,因此程序的運行環境中必須提供相應的庫。動態函數庫的改變並不影響你的程序,因此動態函數庫的升級比較方便。開發
使用靜態庫的好處:
1,模塊化,分工合做
2,避免少許改動常常致使大量的重複編譯鏈接
3,也能夠重用,注意不是共享使用
使用動態庫的好處:
1,能夠將最終可執行文件體積縮小
2,多個應用程序共享內存中得同一份庫文件,節省資源
3,能夠不從新編譯鏈接可執行程序的前提下,更新動態庫文件達到更新應用程序的目的。
不管是靜態庫文件仍是動態庫文件,都是由目標文件(即 .o 文件)建立的,注意庫中函數不能有main函數。
靜態庫的應用
1) 靜態庫的建立
靜態庫文件的命名規範是以lib開頭,以.a結尾。如libmymath.a
ar cr libmymath.a mymath.o
2) 靜態庫的使用
①直接連接
gcc main.c libmymath.a
②在使用到這些公用函數的源程序中包含這些公用函數的原型聲明,而後再用gcc命令生成目標文件時指明所使用的靜態庫名(是mymath 而不是libmymath.a ),gcc將會從靜態庫中將公用函數鏈接到目標文件中。注意,gcc會自動在靜態庫名前加上前綴lib,而後追加擴展名.a獲得的靜態庫文件名來查找靜態庫文件。
gcc main.c -L. -lmymath
參數說明:-L指明靜態庫文件所在路徑,-l指明所要使用的靜態庫。
動態庫的應用
1) 動態庫的建立
動態庫文件名命名規範與靜態庫相似,以lib開頭,以.so結尾。如:libmymath.so。
gcc -shared -fPCI -o libmymath.so mymath.o
注意-fPIC選項。PIC指Position Independent Code。共享庫要求有此選項,以便實現動態鏈接(dynamic linking)。表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的因此動態載入時是經過代碼拷貝的方式來知足不一樣進程的須要,而不能達到真正代碼段共享的目的。
2) 動態庫的使用
①直接連接
gcc main.c ./libmymath.so
②與靜態庫的使用基本一致,參數意義也相同,編譯器會先搜索libxxx.so文件,若是沒有找到,繼續搜索libxxx.a(靜態庫)。
gcc main.c -L. -lmymath
加載動態庫生成的可執行文件運行時一樣須要使用該動態庫,所以必須告訴程序該動態庫的路徑,不然程序運行將會出錯。
爲了讓執行程序順利找到動態庫,有三種方法:
①把庫拷貝到/usr/lib和/lib目錄下。
②在LD_LIBRARY_PATH環境變量中加上庫所在路徑。例如動態庫libmymath.so在當前目錄下。‘.’表示當前目錄,用‘:’隔開
使用命令:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
③修改/etc/ld.so.conf文件,把庫所在的路徑加到文件末尾,並執行sudo ldconfig刷新(須要超級用戶權限)。
注:
查看依賴動態庫庫命令:ldd
查看可執行文件的符號:nm