2010-04-15 110 views
428

靜態庫和共享庫有什麼區別?靜態庫和共享庫之間的區別?

我使用Eclipse,並且有幾個項目類型,包括靜態庫和共享庫?一個人比另一個人有優勢嗎?

+3

維基百科有靜態,動態和共享庫之間的區別的[很好的描述(http://en.wikipedia.org/wiki/Library_%28computing%29)。 – 2010-04-15 22:13:56

回答

595

共享庫。所以(的能力或在Windows .dll或OS X .dylib)文件中。所有與庫相關的代碼都在這個文件中,並且在運行時被程序使用。使用共享庫的程序僅引用它在共享庫中使用的代碼。

靜態庫是.a(或在Windows .lib中)文件。所有與庫有關的代碼都在這個文件中,並且它在編譯時直接鏈接到程序中。使用靜態庫的程序從靜態庫中獲取它使用的代碼的副本,並將其作爲程序的一部分。 [Windows也有。lib文件用於引用.dll文件,但它們的作用與第一個文件相同]。

每種方法都有優點和缺點。

共享庫減少在每個,使得使用該庫的程序複製的代碼量,保持二進制小。它還允許您用功能相同的替換共享對象,但可能增加了性能優勢,而無需重新編譯使用它的程序。然而,共享庫對於執行函數以及運行時加載成本都會有小的額外成本,因爲庫中的所有符號都需要連接到它們使用的東西。另外,共享庫可以在運行時加載到應用程序中,這是實現二進制插件系統的一般機制。

靜態庫增加了二進制的整體大小,但它意味着你不需要沿着正在使用的庫的副本攜帶。由於代碼在編譯時連接,所以沒有任何額外的運行時加載成本。代碼就在那裏。個人而言,我更喜歡共享庫,但在需要確保二進制文件沒有很多可能難以滿足的外部依賴性時使用靜態庫,例如特定版本的C++標準庫或特定版本的Boost C++庫。

+2

的一部分「替換爲共享對象...功能上等同的,但可能[改善]性能」:特別,相當於在語義使用API​​的功能面臨主叫方(應用程序編程接口:函數簽名和變量,包括類型),但實現端功能可以在比PERF:例如,功能更會隨時記錄到文件不同 - >也登錄到TCP服務器:端口預計爲$ MY_APP_LOG_SERVER。 – 2014-02-21 06:19:37

+1

「[.sos incur a]小額外成本爲功能」執行 - 這是*可能*(如果功能組/排序已經爲高速緩存位置在靜態鏈接進行優化,或由於OS古怪/裝載機/編譯器/像跨網段/大指針PERF架構。懲罰),但是在許多體系結構/編譯器設置中,動態鏈接器將調用打補丁以創建完全相同的調用機器操作碼。 – 2014-02-21 06:36:43

+2

「由於代碼在編譯時連接,所以沒有任何額外的運行時加載成本,代碼就在那裏。」 - 是的,沒有...它所有的可執行映像準備在被尋呼,如果在執行要求,但是 - 從你的程序還沒有運行最近足夠緩存的情況下開始 - 與共享庫這是可能的(有時可能或某些)操作系統,驅動程序或其他正在運行的程序已經加載了您的應用程序要使用的共享庫,在這種情況下,它可能在緩存中,並且程序啓動並運行得更快。 – 2014-02-21 06:40:35

24

對於靜態庫,代碼從庫鏈接器,提取並使用在編譯/構建應用程序的角度來構建最終的可執行文件。最終的可執行文件在運行時對庫沒有依賴關係

對於共享庫,編譯器/鏈接程序在生成應用程序時檢查鏈接的名稱是否存在於庫中,但不會將其代碼移入應用程序。運行時,共享庫必須可用。

C編程語言本身沒有靜態或共享庫的概念 - 他們是完全實現的功能。

就個人而言,我更喜歡使用靜態庫,因爲它使軟件分發簡單。然而,這是一個意見,過去有多少(比喻)血液流出。

+3

+1「C編程語言本身沒有靜態或共享庫的概念 - 它們完全是一個實現功能。「 – Tiger 2016-03-08 14:22:22

14

共享庫的最顯著的優點是,只有一個在內存中加載代碼副本,無論有多少進程如何使用圖書館。對於靜態庫,每個進程都會獲得自己的代碼副本。這可能會導致顯着的內存浪費。

OTOH,靜態庫的一個優點是所有東西都捆綁到您的應用程序中。因此,您不必擔心客戶端系統上可以使用正確的庫(和版本)。

+1

可執行映像較大磁盤上,以及在內存中,使用靜態庫時。 – JustJeff 2010-04-15 22:19:32

+0

那是正確的,這就是我在影射我說一切都捆綁到應用程序中。 – Jasmeet 2010-04-15 22:40:54

46

簡化:

  • 靜態鏈接:一個大的可執行
  • 動態鏈接:一個小的可執行加上一個或多個庫文件(在Windows .dll文件,。所以在Linux上,或名爲.dylib在MacOS )
26

靜態庫被編譯爲應用程序的一部分,而共享庫都沒有。當您分發依賴於共享庫的應用程序時,庫,例如。需要安裝MS Windows上的dll。

靜態庫的優點是,有運行的應用程序爲用戶無需依賴關係 - 例如他們不必升級他們的任何DLL ......缺點是你的應用程序的體積較大,因爲你正在運送它所需的所有庫。

除了爲龍頭,以較小的應用程序,共享庫提供給用戶使用自己的,也許更好的版本庫中而不是依靠一個是應用程序的一部分

+2

DLL地獄,因爲它已經知道 – gheese 2013-11-01 15:45:19

+1

「靜態庫被編譯爲應用程序的一部分」 ...靜態庫被編譯爲靜態庫和鏈接作爲應用 – user463035818 2017-07-12 10:23:01

323

靜態庫就像書店,共享庫就像一個庫。與前者一樣,你可以將自己的書/功能副本帶回家;與後者,你和其他人去圖書館使用相同的書/功能。所以任何想要使用(共享)庫的人都需要知道它在哪裏,因爲你必須「去」獲取書/功能。通過一個靜態庫,這本書/函數是你自己擁有的,並且將它保存在你的家庭/程序中,一旦你擁有了它,你就不會在意何時何地獲得它。

2

在所有其他答案的上方,有一件事不mentionned尚未被解耦:

讓我談談現實世界的生產代碼,我一直在處理:

一個非常大的軟件,由> 300個項目(使用Visual Studio),主要是建設成爲靜態庫最後全部鏈接在一起,在一個巨大的可執行文件,你結束了以下問題:

-Link時間極長。你可能最終需要超過15分鐘的鏈接,比如說編譯時間爲10s - 有些工具正在他們的膝蓋上,這樣一個很大的可執行文件,比如內存檢查工具,必須對代碼進行測試。你可能會陷入被認爲是愚蠢的極限。

更成問題的是你的軟件的解耦:在這個現實世界的例子,標題每個項目的文件來自其他任何項目reacheable。因此,一個開發人員添加依賴關係非常容易;它只是包括標題,因爲鏈接最後會全部找到符號。它最終由可怕的自行車依賴和完全混亂。

爲共享庫,它是一些額外的工作,因爲開發人員必須修改項目構建系統添加依賴庫。我觀察到共享庫代碼傾向於提供更乾淨的代碼API。