動態庫和靜態庫

2021-06-07 07:45:50 字數 2347 閱讀 8752

本文主要解決以下幾個問題

1 為什麼要使用庫?

2 庫的分類

3 建立自己的庫

或許大家對自己初學linux時的情形仍記憶尤新吧。如果沒有乙個能較好的解決依賴關係的包管理器,在linux下安裝軟體將是一件及其痛苦的工作。你裝a包時,可能會提示你要先裝b包,當你費盡心力找到b包時,可能又會提示你要先安裝c包。我就曾被這樣的事搞的焦頭爛額,至今一提起rpm仍心有餘悸,頭皮發麻。說是一朝被蛇咬,十年怕井繩怕也不為過。

linux下之所以有這許多的依賴關係,其中乙個開發原則真是功不可沒。這個原則就是:盡量不重複做別人已經做過的事。換句話說就是盡量充分利用別人的勞動成果。

這就涉及到如何有效的進行**復用。

1 為什麼要使用庫?

關於**復用的途徑,一般有兩種。

貼上複製

這是最沒有技術含量的一種方案。如果**小,則工作量還可以忍受,如果**很龐大,則此法不可取。即便有人原意這樣做,但誰又能保證所有的**都可得到呢?

而庫的出現很好的解決了這個問題。

庫,是一種封裝機制,簡單說把所有的源**編譯成目標**後打成的包。

那麼使用者怎麼能知道這個庫提供什麼樣的介面呢?難道要用nm等工具逐個掃瞄?

不用擔心,庫的開發者早以把一切都做好了。除了包含目標**的庫外,

www.linuxidc.com

一般還會提供一系列的標頭檔案,標頭檔案中就包含了庫的介面。為了讓方便使用者,再加上乙個使用說明就差不多完美了。

2 庫的分類

2.1 庫的分類

根據鏈結時期的不同,庫又有靜態庫和動態庫之分。

靜態庫是在鏈結階段被鏈結的(好像是廢話,但事實就是這樣),所以生成的可執行檔案就不受庫的影響了,即使庫被刪除了,程式依然可以成功執行。

有別於靜態庫,動態庫的鏈結是在程式執行的時候被鏈結的。所以,即使程式編譯完,庫仍須保留在系統上,以供程式執行時呼叫。(todo:鏈結動態庫時鏈結階段到底做了什麼)

2.2 靜態庫和動態庫的比較

鏈結靜態庫其實從某種意義上來說也是一種貼上複製,只不過它操作的物件是目標**而不是原始碼而已。因為靜態庫被鏈結後庫就直接嵌入可執行檔案中了,這樣就帶來了兩個問題。

首先就是系統空間被浪費了。這是顯而易見的,想象一下,如果多個程式鏈結了同乙個庫,則每乙個生成的可執行檔案就都會有乙個庫的副本,必然會浪費系統空間。

再者,人非聖賢,即使是精心除錯的庫,也難免會有錯。一旦發現了庫中有bug,挽救起來就比較麻煩了。必須一一把鏈結該庫的程式找出來,然後重新編譯。

而動態庫的出現正彌補了靜態庫的以上弊端。因為動態庫是在程式執行時被鏈結的,所以磁碟上只須保留乙份副本,因此節約了磁碟空間。如果發現了bug或要公升級也很簡單,只要用新的庫把原來的替換掉就行了。

那麼,是不是靜態庫就一無是處了呢?

答曰:非也非也。不是有句話麼:存在即是合理。靜態庫既然沒有湮沒在滔滔的歷史長河中,就必然有它的用武之地。想象一下這樣的情況:如果你用libpcap庫編了乙個程式,要給被人執行,而他的系統上沒有裝pcap庫,該怎麼解決呢?最簡單的辦法就是編譯該程式時把所有要鏈結的庫都鏈結它們的靜態庫,這樣,就可以在別人的系統上直接執行該程式了。

所謂有得必有失,正因為動態庫在程式執行時被鏈結,故程式的執行速度和鏈結靜態庫的版本相比必然會打折扣。然而瑕不掩瑜,動態庫的不足相對於它帶來的好處在現今硬體下簡直是微不足道的,所以鏈結程式在鏈結時一般是優先鏈結動態庫的,除非用-static引數指定鏈結靜態庫。

2.3 如何判斷乙個程式有沒有鏈結動態庫?

答案是用file實用程式。

file程式是用來判斷檔案型別的,在file命令下,所有檔案都會原形畢露的。

另外,還可以借助程式ldd實用程式來判斷。

ldd是用來列印目標程式(由命令列引數指定)所鏈結的所有動態庫的資訊的,如果目標程式沒有鏈結動態庫,則列印「nota dynamic executable」,ldd的用法請參考manpage。

3 建立自己的庫

3.1 建立動態庫

建立檔案hello.c,內容如下:

#include

void hello(void)

用命令gcc -shared hello.c-o libhello.so編譯為動態庫。可以看到,當前目錄下多了乙個檔案libhello.so。

[leo@leo test]$ filelibhello.so

libhello.so: elf 32-bitlsb shared object, intel 80386, version 1 (sysv), not stripped

看到了吧,檔案型別是sharedobject了。

intmain()

這下可以編譯了:)

[leo@leo test]$ gcctest.c

/tmp/ccm7w6mn.o: infunction `main':

源文件 <> 

動態庫和靜態庫

先抄一段 windows下的動態庫和靜態庫區別解釋,其實linux下意義一樣的,不過字尾名有些區別 靜態庫 在編譯的時候載入生成目標檔案,在執行時不用載入庫,在執行時對庫沒有依賴性。動態庫 在目標檔案執行時載入,手動載入,且對庫有依賴性。兩者區別 一,靜態庫的使用需要 1 包含乙個對應的標頭檔案告知...

動態庫和靜態庫

簡單的說,使用動態庫就是在鏈結的時候,不會將動態庫的 鏈結到可執行檔案中,而是採用symbol的方式。使用靜態庫,生成可執行檔案的時候,會將靜態庫的 鏈結到可執行檔案中。這樣,動態庫體積會很小,並且可以,依賴於更新的動態庫,但是,缺點是不穩定。靜態庫會更加穩定,但是體積會很大。靜態庫 就是多個目標檔...

動態庫和靜態庫

靜態庫和動態庫 二進位制級別的 復用 封裝函式或類,供程式呼叫,是二進位制檔案,最多只能被反編譯成彙編 動態庫 dynamic link library,動態鏈結庫或共享庫 shared object 只是把要鏈結的動態庫的相關資訊 名字,符號表等 嵌入到可執行檔案中去,在執行時呼叫相應的動態庫。動...