2011-06-24 249 views
0

誰能給我解釋一下什麼是GCC中的共享和靜態庫之間的差異(生成文件)共享和靜態庫

,我讀了靜態庫是獨立的代碼,但它會增加你的exectuable文件的大小

但共享庫它動態鏈接的功能,它不會增加您的可執行文件的大小

我不明白這兩者之間的區別。

任何人都可以告訴我什麼時候應該創建一個靜態庫,什麼時候我應該創建一個共享庫。

他們說,共享庫是依賴於位置的代碼

什麼我們所說的與位置相關的代碼?

如果共享庫不增加代碼,並且靜態庫增加了代碼大小 那麼我們可以直接使用共享庫。

但是爲什麼我們也有靜態庫呢?它的真正用處是什麼。

請幫我傢伙

+1

動態庫作爲獨立的文件必須存在沿着可執行系統上,而只有在編譯時需要靜態庫存在。使用靜態庫的主要原因之一是避免在系統中存在多個版本的庫時發生衝突,並且可能與鏈接到可執行文件的版本衝突。 – SirDarius

+0

(從標籤和標題中刪除「makefile」,因爲這與makefile無關。) – Beta

+0

共享庫始終具有與位置無關的代碼。靜態庫可以有獨立的或獨立的。 – 2011-06-24 21:53:22

回答

2

當您使用gcc編譯代碼時,它可以直接生成目標文件,並且可以將多個目標文件鏈接在一起以生成可執行文件。

靜態庫只是一個目標文件(通常帶有索引)的集合,它可以在創建可執行文件時由鏈接器使用。

將目標文件鏈接在一起並鏈接到一個靜態庫的區別在於,對於該庫,鏈接器只會從其中選擇絕對需要的目標文件,而鏈接目標文件時鏈接器將被強制拿走所有的文件。

動態庫又不同 - 非常不同。它是一個目標文件的集合,但是這次它的所有內部鏈接的鏈接過程的輸出已經解決了。

鏈接動態庫意味着鏈接程序只解析最終可執行文件中的符號,但鏈接時不添加庫中的目標代碼。

運行與動態庫鏈接的可執行意味着在運行時一些特殊的軟件,有權要求操作系統到指定的動態庫加載到內存中(這就是爲什麼一個動態庫必須通過接頭創建)通常在節目到達main()之前。

這個可執行文件可以是磁盤上的一個非常小的文件,但是當加載到內存中,並加載動態庫的總內存圖像庫的整體將在已加載可能相當大了。

我相信它的情況下,如果幾個不同的程序需要相同的動態庫,操作系統可以爲每個程序使用虛擬內存來加載庫,但這隻使用一個物理內存副本 - 這在某些情況下可以節省很多。

如果您發佈需要動態庫的可執行文件,那麼您可能很幸運,該文件可能已經在用戶的機器上。如果沒有,你也必須安裝它。但是,如果您在庫中發現錯誤,那麼只需發送新版本的動態庫即可修復這些錯誤。

用靜態庫構建的可執行文件已準備就緒,但修復錯誤將涉及重新傳輸整個可執行文件。

總結:

 
       object files static library dynamic library 
produced by compiler  librarian  linker 
exe   large   smaller   smallest 
ram x 1 copy large   smaller   largest 
ram x n copies large   smaller   smallest 
dep on files independent independent  dependant 
upgrade lib no   no    yes 
+0

我以爲這有點含糊不清,「那麼只要發佈一個新的動態庫就可以修復這些bug。」我認爲如果你說「那麼只是發佈一個新版本* *動態庫將修復錯誤 - 你不需要用它發佈一個新的可執行文件就會更清楚。」 – Will

0
  • 你可能希望在不將庫的依賴,創造一個單一的可執行文件。
  • 據我所知靜態庫應該有點快。

缺點:連接共享庫不僅增加了每個可執行文件也會加載的可執行文件大小。如果您在多個可執行文件中使用該庫,那麼它將多次存儲在內存中。

位置相關代碼意味着在庫的創建時,庫的確切位置並不知道,因此只有相對內存尋址可用(例如:從該指令跳轉到+50字節並從該處執行)

+0

大多數操作系統實際上將共享共享庫的只讀部分的內存映射以及從相同底層文件加載該庫的所有進程。這實際上是共享庫的優點之一,而不是缺點。 – acm