c++ - static library dynamic library




靜態庫和共享庫之間的區別? (5)

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

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

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

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

靜態庫會增加二進製文件的整體大小,但這意味著您不需要攜帶正在使用的庫的副本。 由於代碼在編譯時連接,所以沒有任何額外的運行時加載成本。 代碼就在那裡。

就個人而言,我更喜歡共享庫,但在需要確保二進製文件沒有很多可能難以滿足的外部依賴性時使用靜態庫,例如特定版本的C ++標準庫或特定版本的Boost C ++庫。

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

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


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

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


簡化:

  • 靜態鏈接:一個大的可執行文件
  • 動態鏈接:一個小的可執行文件加上一個或多個庫文件(Windows上的.dll文件,Linux上的.so或macOS上的.dylib)

除了所有其他答案之外,尚未提及的一件事就是解耦:

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

一個非常大的軟件,由大於300個項目(使用visual studio)製作而成,大多數都是靜態庫,最後所有這些都以一個巨大的可執行文件鏈接在一起,最終會出現以下問題:

鏈接時間非常長。 你可能最終需要15分鐘以上的鏈接,比如說10秒的編譯時間 - 有些工具在他們的膝蓋上有著如此大的可執行文件,比如內存檢查工具,它們必須對代碼進行測試。 你可能會陷入被認為是愚蠢的極限。

更麻煩的是你的軟件解耦:在這個真實世界的例子中,每個項目的頭文件都可以從任何其他項目中重新獲得。 因此,一個開發人員添加依賴關係非常容易; 它只是包括標題,因為鏈接最後會全部找到符號。 它最終由可怕的自行車依賴和完全混亂。

對於共享庫,這是一項額外的工作,因為開發人員必須編輯項目構建系統以添加相關庫。 我觀察到共享庫代碼傾向於提供更乾淨的代碼API。


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

靜態庫的優點在於運行應用程序的用戶不需要任何依賴關係 - 例如,他們不必升級其任何DLL的DLL ...缺點是您的應用程序的體積較大,因為您將它與它需要的所有庫。

除了導致更小的應用程序外,共享庫還使用戶能夠使用自己的,也許更好的庫版本,而不是依賴於應用程序的一部分





static-libraries