動態庫和靜(jing)態庫的區別
時間:2018-09-26 來(lai)源:未知
一、什么是庫
本(ben)質上來說(shuo)庫(ku)是一種可(ke)執行代碼(ma)的二進(jin)制形式(shi),可(ke)以被操作系統載入內存執行。
二、庫的種類
linux下的庫(ku)有(you)兩(liang)種:靜態庫(ku)和共享庫(ku)(動態庫(ku))。
三、命名方式
靜態(tai)庫:lib庫名.a
動態(tai)庫:lib庫名.so
區(qu)分一(yi)個概(gai)念:庫是包含前(qian)綴lib以及后綴.a或者.so的(de)一(yi)個整體
庫(ku)名是去掉前綴和(he)后綴剩下的部分
四、動態庫和靜態庫的特點
靜態庫的特點:
1、使(shi)用靜(jing)態庫(ku)的時候,會將靜(jing)態庫(ku)的信息直接編譯到可(ke)執行文件(jian)中
2、優點:當靜(jing)態庫被刪除,對可執行文件沒有影響(xiang)
3、缺點:浪費內(nei)存(cun)空間。如果靜態庫(ku)被修改,可執行(xing)程序要重新(xin)編譯
動態(tai)(tai)(tai)庫(ku)(ku)的(de)特點:加載(zai)器(qi)在加載(zai)動態(tai)(tai)(tai)庫(ku)(ku)時(shi),操(cao)作系統會先檢(jian)查動態(tai)(tai)(tai)庫(ku)(ku)是否因為其它(ta)程(cheng)序已(yi)(yi)經(jing)將這(zhe)個動態(tai)(tai)(tai)庫(ku)(ku)信息(xi)加載(zai)到了內(nei)存中。如果(guo)(guo)沒(mei)有加載(zai)到內(nei)存中,操(cao)作系統會將動態(tai)(tai)(tai)庫(ku)(ku)載(zai)入內(nei)存,并將它(ta)的(de)引(yin)用(yong)計數(shu)(shu)設置為1;如果(guo)(guo)已(yi)(yi)經(jing)加載(zai)到內(nei)存,僅將動態(tai)(tai)(tai)庫(ku)(ku)的(de)引(yin)用(yong)計數(shu)(shu)加1。
五、如何知道一個可執行程序依賴哪些庫
ldd命令可(ke)以(yi)查看一個可(ke)執行程序依賴的共享庫
例如# ldd + 路(lu)徑(jing)/可(ke)執行(xing)程(cheng)序
六、創建靜態庫和動態庫的過程
靜態庫(ku):a、創建.o文件
b、ar -cr lib庫(ku)名.a *.o
動(dong)態庫: a、創建.o文件 要(yao)使用-fpic選(xuan)項
“-fpic”告訴GCC產生的代(dai)碼(ma)不要包含對函數和變量具(ju)體(ti)內存位置的引(yin)用,這(zhe)是(shi)因為現在還無法(fa)知道使用該代(dai)碼(ma)的應(ying)用程(cheng)序(xu)會將它連接到哪一(yi)段內存地址(zhi)空間。這(zhe)樣編(bian)譯出的hello.o可以被用于建立共享鏈接庫。
b、 gcc -shared -o lib庫名(ming).so *.o
七、如何使用庫
靜態庫:
a、如果靜態庫放在(zai)系統目錄/lib或者/usr/lib下(xia)
執行(xing)方(fang)式(shi)為 gcc main.c -l庫(ku)名
b、如果靜態庫(ku)沒有放在系統目錄下則(ze)執行方式為執行 gcc main.c -L 靜態庫(ku)路徑(jing) -l 庫(ku)名。或者執行gcc main.c 路徑(jing)/整個(ge)靜態庫(ku)
動態庫:
a、如果(guo)放在(zai)系統(tong)目錄下執行方式為 gcc main.c -l庫(ku)名
b、如果沒有放在系統目錄(lu)下執行方式分(fen)為(wei)兩種:
第(di)一種:執行 gcc main.c -L 動態(tai)庫路徑 -l 庫名,不過這種方式在(zai)執行可執行程序的(de)時候可能出現如下錯誤
./a.out: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
解決方式:
1、在/etc/bash.bashrc文件中添(tian)加(jia)export LD_LIBRARY_PATH=$LD_LRBRARY_PATH:動態(tai)庫(ku)的絕(jue)對路(lu)徑(jing)。后source /etc/bash.bashrc
2、在/etc/ld.so.conf.d目(mu)錄下創建一個(ge)以.conf為后綴的文(wen)件,在這(zhe)個(ge)文(wen)件中添加上動態(tai)庫的絕對路徑,后執行sudo ldconfig
ldconfig命令的用途,主(zhu)要是在(zai)默認搜尋目錄(/lib和/usr/lib)以及動(dong)態庫(ku)配置文件(jian)/etc/ld.so.conf內所列的目錄下,搜索出可(ke)共享(xiang)的動(dong)態鏈接庫(ku).
第二種(zhong):如果(guo)第一種(zhong)的方式都配(pei)置完之后出現(xian)如下(xia)錯誤
/usr/bin/ld: cannot find -laddsub
collect2: ld returned 1 exit status
這種錯誤說明(ming)編(bian)譯(yi)器(qi)找不到需要鏈接的庫(ku)(ku),則執行gcc main.c 動態庫(ku)(ku)路(lu)徑/動態庫(ku)(ku)

