靜態(tài)鏈接庫(kù)组贺、動(dòng)態(tài)鏈接庫(kù)凸舵、導(dǎo)入庫(kù)的區(qū)別

一、前言

通常情況下失尖,對(duì)函數(shù)庫(kù)的鏈接是放在編譯時(shí)期(compile time)完成的啊奄。所有相關(guān)的對(duì)象文件 (object file)與牽涉到的函數(shù)庫(kù)(library)被鏈接合成一個(gè)可執(zhí)行文件 (executable file)渐苏。程序 在運(yùn)行 時(shí),與函數(shù)庫(kù)再無(wú)瓜葛菇夸,因?yàn)樗行枰暮瘮?shù)已拷貝到自己門下琼富。所以這些函數(shù)庫(kù)被成為靜態(tài)庫(kù)(static libaray),通常文件 名為“l(fā)ibxxx.a”的形式庄新。其實(shí)鞠眉,我們也可以把對(duì)一些庫(kù)函數(shù)的鏈接載入推遲到程序運(yùn)行的時(shí)期(runtime)。這就是如雷貫耳的動(dòng)態(tài)鏈接庫(kù)(dynamic link library)技術(shù)择诈。

二械蹋、動(dòng)態(tài)鏈接

動(dòng)態(tài)鏈接方法:LoadLibrary()/GetProcessAddress()和FreeLibrary(),使用這種方式的程序并不在一開始就完成動(dòng)態(tài)鏈接羞芍,而是直到真正調(diào)用動(dòng)態(tài)庫(kù)代碼時(shí)哗戈,載入程序才計(jì)算(被調(diào)用的那部分)動(dòng)態(tài)代碼的邏輯地址,然后等到某個(gè)時(shí)候荷科,程序又需要調(diào)用另外某塊動(dòng)態(tài)代碼時(shí)唯咬,載入程序又去計(jì)算這部分代碼的邏輯地址,所以步做,這種方式使程序初始化時(shí)間較短副渴,但運(yùn)行期間的性能比不上靜態(tài)鏈接的程序。

三全度、靜態(tài)鏈接

靜態(tài)鏈接方法:#pragma comment(lib, "test.lib") 煮剧,靜態(tài)鏈接的時(shí)候,載入代碼就會(huì)把程序會(huì)用到的動(dòng)態(tài)代碼或動(dòng)態(tài)代碼的地址確定下來(lái)
靜態(tài)庫(kù)的鏈接可以使用靜態(tài)鏈接将鸵,動(dòng)態(tài)鏈接庫(kù)也可以使用這種方法鏈接導(dǎo)入庫(kù)

四勉盅、靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別

在軟件開發(fā)的過(guò)程中,大家經(jīng)常會(huì)或多或少的使用別人編寫的或者系統(tǒng)提供的動(dòng)態(tài)庫(kù)或靜態(tài)庫(kù)顶掉,但是究竟是使用靜態(tài)庫(kù)還是動(dòng)態(tài)庫(kù)呢草娜?他們的適用條件是什么呢?

簡(jiǎn)單的說(shuō)痒筒,靜態(tài)庫(kù)和應(yīng)用程序編譯在一起宰闰,在任何情況下都能運(yùn)行,而動(dòng)態(tài)庫(kù)是動(dòng)態(tài)鏈接簿透,顧名思義就是在應(yīng)用程序啟動(dòng)的時(shí)候才會(huì)鏈接移袍,所以,當(dāng)用戶的系統(tǒng)上沒(méi)有該動(dòng)態(tài)庫(kù)時(shí)老充,應(yīng)用程序就會(huì)運(yùn)行失敗葡盗。再看它們的特點(diǎn):

動(dòng)態(tài)庫(kù):

  • 類庫(kù)的名字一般是 libxxx.so
  • 共享:多個(gè)應(yīng)用程序可以使用同一個(gè)動(dòng)態(tài)庫(kù),啟動(dòng)多個(gè)應(yīng)用程序的時(shí)候啡浊,只需要將動(dòng)態(tài)庫(kù)加載到內(nèi)存一次即可觅够;
  • 開發(fā)模塊好:要求設(shè)計(jì)者對(duì)功能劃分的比較好胶背。
  • 動(dòng)態(tài)函數(shù)庫(kù)的改變并不影響你的程序,所以動(dòng)態(tài)函數(shù)庫(kù)的升級(jí)比較方便喘先。

靜態(tài)庫(kù):

  • 類庫(kù)的名字一般是libxxx.a
  • 代碼的裝載速度快钳吟,執(zhí)行速度也比較快,因?yàn)榫幾g時(shí)它只會(huì)把你需要的那部分鏈接進(jìn)去苹祟。
  • 應(yīng)用程序相對(duì)比較大砸抛,如果多個(gè)應(yīng)用程序使用的話,會(huì)被裝載多次树枫,浪費(fèi)內(nèi)存直焙。
  • 如果靜態(tài)函數(shù)庫(kù)改變了,那么你的程序必須重新編譯砂轻。

如果你的系統(tǒng)上有多個(gè)應(yīng)用程序都使用該庫(kù)的話奔誓,就把它編譯成動(dòng)態(tài)庫(kù),這樣雖然剛啟動(dòng)的時(shí)候加載比較慢搔涝,但是多任務(wù)的時(shí)候會(huì)比較節(jié)省內(nèi)存厨喂;如果你的系統(tǒng)上只有一到兩個(gè)應(yīng)用使用該庫(kù),并且使用的API比較少的話庄呈,就編譯成靜態(tài)庫(kù)吧蜕煌,一般的靜態(tài)庫(kù)還可以進(jìn)行裁剪編譯,這樣應(yīng)用程序可能會(huì)比較大诬留,但是啟動(dòng)的速度會(huì)大大提高斜纪。

五、例子詳解

文件目錄樹如下:

  1. libtest/
  2. |-- myjob.c
  3. |-- myjob.h
  4. |-- test.c

靜態(tài)庫(kù)

A.做成靜態(tài)庫(kù) libmyjob.a

$ gcc -c myjob.c -o myjob.o 
$ ar -c -r -s libmyjob.a myjob.o

B.鏈接

$ gcc test.o libmyjob.a -o test 

C.引用庫(kù)情況(無(wú)所要信息)

$ ldd test 
linux-gate.so.1 => (0xffffe000) 
libc.so.6 => /lib/libc.so.6 (0xb7e29000) 
/lib/ld-linux.so.2 (0xb7f6e000) 

動(dòng)態(tài)庫(kù)

A.做成動(dòng)態(tài)庫(kù)libmyjob.so

$ gcc -Wall –fPIC -c myjob.c -o myjob.o   
$ gcc -shared -o libmyjob.so myjob.o   
  • -shared: 該選項(xiàng)指定生成動(dòng)態(tài)連接庫(kù)(讓連接器生成T >類型的導(dǎo)出符號(hào)表文兑,有時(shí)候也生成弱連接 W >類型的導(dǎo)出符號(hào))盒刚,不用該標(biāo)志外部程序無(wú)法連接。相當(dāng)于一個(gè)可執(zhí)行文件绿贞。
  • -fPIC: 表示編譯為位置獨(dú)立的代碼因块,不用此選項(xiàng)的話編譯后的代碼是位置相關(guān)的所以動(dòng)>>態(tài)載入時(shí)是通過(guò)代碼拷貝的方式來(lái)滿足不同進(jìn)程的需要,而不能達(dá)到真正代碼段共享的目的>籍铁。
  • -L.: 表示要連接的庫(kù)在當(dāng)前目錄中涡上。
    LD_LIBRARY_PATH: 這個(gè)環(huán)境變量指示動(dòng)態(tài)連接器可以裝載動(dòng)態(tài)庫(kù)的路徑。

B.鏈接
鏈接方法一拒名、拷貝到系統(tǒng)庫(kù)里再鏈接吓懈,讓 gcc 自己查找:

$ cp libmyjob.so /usr/lib 
$ gcc -o test test.o -lmyjob 

這里我們可以看到了 -lmyjob 選項(xiàng), -l[lib_name] 指定庫(kù)名靡狞,他會(huì)主動(dòng)搜索。 lib[lib_name].so 這個(gè)搜索的路徑可以通過(guò) gcc --print-search-dirs 來(lái)查找隔嫡。

鏈接方法二 甸怕,手動(dòng)指定庫(kù)路徑

$  gcc -o test test.o -lmyjob -B /path/to/lib

-B 選項(xiàng)就添加 /path/to/lib 到 gcc 搜索的路徑之中甘穿。這樣鏈接沒(méi)有問(wèn)題但是方法 II 中手動(dòng)鏈接好的程序在 執(zhí)行 時(shí)候仍舊需要指定庫(kù)路徑( 鏈接和執(zhí)行是分開的 )。需要添加系統(tǒng)變量 LD_LIBRARY_PATH :

   1. $ export LD_LIBRARY_PATH=/path/to/lib 
這個(gè)時(shí)候再來(lái)檢測(cè)一下test 程序的庫(kù)鏈接狀況 ( 方法 I 情況 )
   1. $ ldd test 
   2. linux-gate.so.1 => (0xffffe000) 
   3. libmyjob.so => /usr/lib/ libmyjob .so (0xb7f58000) 
   4. libc.so.6 => /lib/libc.so.6 (0xb7e28000) 
   5. /lib/ld-linux.so.2 (0xb7f6f000) 

是不是比靜態(tài)鏈接的程序多了一個(gè) libmyjob.so? 這就是靜態(tài)與動(dòng)態(tài)的最大區(qū)別梢杭,靜態(tài)情況下温兼,它把庫(kù)直接加載到程序里,而在動(dòng)態(tài)鏈接的時(shí)候武契,它只是保留接口募判,將動(dòng)態(tài)庫(kù)與程序代碼獨(dú)立。這樣就可以提高代碼的可復(fù)用度咒唆,和降低程序的耦合度届垫。
另外,運(yùn)行時(shí)全释,要保證主程序能找到動(dòng)態(tài)庫(kù)装处,所以動(dòng)態(tài)庫(kù)一般發(fā)布到系統(tǒng)目錄中,要么就在跟主程序相對(duì)很固定的路徑里浸船,這樣不管主程序在本機(jī)何時(shí)何地跑妄迁,都能找得到動(dòng)態(tài)庫(kù)。而靜態(tài)庫(kù)只作用于鏈接時(shí)李命,運(yùn)行主程序時(shí)靜態(tài)庫(kù)文件沒(méi)存在意義了登淘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市封字,隨后出現(xiàn)的幾起案子黔州,更是在濱河造成了極大的恐慌,老刑警劉巖周叮,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辩撑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡仿耽,警方通過(guò)查閱死者的電腦和手機(jī)合冀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)项贺,“玉大人君躺,你說(shuō)我怎么就攤上這事】校” “怎么了棕叫?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)奕删。 經(jīng)常有香客問(wèn)我俺泣,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任伏钠,我火速辦了婚禮横漏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘熟掂。我一直安慰自己缎浇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布赴肚。 她就那樣靜靜地躺著素跺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪誉券。 梳的紋絲不亂的頭發(fā)上指厌,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天,我揣著相機(jī)與錄音横朋,去河邊找鬼仑乌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛琴锭,可吹牛的內(nèi)容都是我干的晰甚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼决帖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼厕九!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起地回,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扁远,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后刻像,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畅买,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年细睡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谷羞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡溜徙,死狀恐怖湃缎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蠢壹,我是刑警寧澤嗓违,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站图贸,受9級(jí)特大地震影響蹂季,放射性物質(zhì)發(fā)生泄漏冕广。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一乏盐、第九天 我趴在偏房一處隱蔽的房頂上張望佳窑。 院中可真熱鬧,春花似錦父能、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至鹃唯,卻和暖如春爱榕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背坡慌。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工黔酥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人洪橘。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓跪者,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親熄求。 傳聞我的和親對(duì)象是個(gè)殘疾皇子渣玲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容