2014-11-04 55 views
0

我知道這些問題之前已經被問到 - 但我仍然無法將所有內容協調到一個整體畫面。鏈接,加載和虛擬內存

  1. 靜態VS動態庫
    • 靜態庫有自己的代碼複製並鏈接到生成的可執行文件
    • 靜態庫只複製所需的模塊鏈接到可執行文件,而不是整個庫實現
    • 靜態庫不需要編譯爲PIC,因爲它們是生成的可執行文件的一部分
    • 動態庫在描述h的存根中複製和鏈接負載/鏈接(?)運行時的功能實現
    • 動態庫可以是PIC或可重定位的
    • 爲什麼存在單獨的靜態和動態庫?以上所有內容似乎都是靜態或動態鏈接器的工作。爲什麼我需要2個實現scanf的庫?
    • 獎金#1共享庫是指什麼?我聽說它被用作(1)總括術語,與庫的同義詞,(2)直接用於動態庫,(3)使用虛擬內存將庫的相同物理內存映射到多個地址空間。你只能用動態庫來做到這一點嗎? (4)在內存中具有相同動態庫的不同版本。
    • (獎金#2)是默認情況下動態或靜態鏈接的標準庫(libc,libC++,stdlibC++,..)嗎?我從來不需要dlopen() ..
  2. 靜態VS動態鏈接
    • 這怎麼比靜態VS動態庫有什麼不同?我不明白爲什麼不只有一個庫,我們使用靜態或動態鏈接器(PIC問題除外)。我們是否應該討論更一般的靜態動態鏈接,而不是談論靜態庫和動態庫?
    • 是仍然在編譯時爲兩者執行的符號分辨率?
  3. 靜態VS動態加載
    • 靜態加載裝置執行它之前複製完整的可執行到MM
    • 動態加載意味着僅可執行標頭執行前複製到MM,附加功能被裝入MM請求時。這與分頁有什麼不同?
    • 如果可執行文件是動態鏈接的,爲什麼不能動態加載?
    • 靜態負載和動態加載可能會或可能不會進行拆遷

我知道有很多事情我感到困惑在這裏 - 我沒有必要找人來解決每個問題。我希望通過列出所有令我困惑的事情,理解這一點的人會看到我理解中的失誤在廣泛的層面上,並且能夠描繪出這些事物如何協作的更大的圖片。

+0

如果在Linux上,請閱讀[Drepper的論文:*如何編寫共享庫*](http://people.redhat.com/drepper/dsohowto.pdf)。這是一篇很長的論文,但它回答了你的大部分問題。 – 2014-11-04 20:45:32

+0

@BasileStarynkevitch謝謝你的論文 - 我會讀它!操作系統的概念差異很大嗎? – user167524 2014-11-04 20:48:32

+0

另請參見[Levine的書:*鏈接器和加載器*](http://www.iecc.com/linker/) – 2014-11-04 20:49:12

回答

2

爲什麼2種LIB加載的

  • 動態節省空間(你不使用foo.lib有數以百計的所有二進制文件相同的代碼拷貝
  • 動態允許foo.lib供應商可以出貨的新版本庫和現有代碼利用它
  • 靜態使依賴管理更容易 - 在t heory二進制可以是一個文件

什麼是 '共享庫'

  • UNIX名稱爲動態庫。 Windows調用DLL它

是否標準庫靜態或動態

  • 取決於平臺。在某些情況下,您可以選擇其他人爲您選擇。例如在windwos上有編譯器開關來說明你是否想要靜態或動態運行時。不是不混淆使用dlopen動態庫的使用 - 見後面

「爲什麼我們談論2不同類型庫的」

通常爲靜態庫是從一個動態的一個不同的格式。通常,一個靜態庫就像任何其他編譯單元一樣被輸入到鏈接器。動態庫通常由鏈接器輸出。它們被用於不同的,即使他們都提供相同的代碼塊到您的應用

符號解析在加載時敲定的DLL

全動態加載。這是dlopen的境界。這是您想要調用庫中的入口點的地方,這些入口點在編譯時可能甚至不存在。使用案例:

  • 插件符合衆所周知的接口,但可以有許多實現(PAM和NSS是很好的例子)。應用程序選擇在運行時從指定文件加載一個或多個實現

  • 應用程序需要加載庫並調用任意函數。想象一下,例如,一個腳本語言如何加載並調用任意方法

要使用你不需要使用的dlopen在UNIX上一個.so。你可以爲它加載(相同的窗口)。要真正動態加載共享lib/dll,您需要dlopen或LoadLibrary

0

請注意,靜態鏈接庫的加載速度更快,因爲所有運行時庫文件的磁盤搜索量都較少。如果這些庫很小,並且非常不尋常,那麼最好是靜態鏈接。如果有像MFC這樣嚴重的版本依賴/功能差異,這些DLL需要不同的名稱。

+1

我不確定這一點,至少在Linux上。 Linux上常用的共享庫(例如'libc.so.6'或'libX11.so.6')已經在RAM中進行了mmap編輯。如果它是靜態鏈接的,則需要從每個可執行文件獲取並從中獲取它。 – 2014-11-05 01:47:03