2009-12-23 81 views
10

鏈接和加載動態庫是否都在運行時發生? 還是僅在運行時纔會加載庫?c語言中鏈接和加載的區別是什麼

+0

http://stackoverflow.com/questions/311882/what-do-statically-linked-and-dynamically-linked-mean/311889#311889 – paxdiablo 2009-12-23 09:19:07

+1

這不是一個確切的重複 – 2009-12-26 04:36:23

回答

14

有關靜態鏈接和動態鏈接之間的區別,請參閱前面的很好的一點。假設你指的是動態鏈接,那麼:

加載和(動態)鏈接都由鏈接器完成 - 在linux和其他Unix相似的這是由/lib/ld.so,這是由在幾乎所有情況下的操作系統。 ld.so依次將加載將您的應用程序 - mygameBinary寫入內存,然後ld.so從文件mygameBinary中讀取它需要的動態鏈接庫列表。

接頭,ld.so,然後依次加載每個這些庫到內存中,例如, libc.so,libpthread.so,libopengl.so,並且看看這些可能需要的其他庫libm.so

一旦裝載完成,然後開始,尋找在命名對象或它們由一個庫或應用程序,和進口導出由另一個庫或應用程序功能的方法。然後鏈接器更改各種引用,有時更新代碼以更新每個庫中未鏈接的數據指針和函數調用,以指向實際數據或函數所在的位置。例如,在mygameBinary中調用printf開始時沒有指向任何東西(實際上它只是調用鏈接器),但在鏈接變爲跳轉到libc中的printf函數之後。

一旦這種連接完成後,啓動應用程序,通過調用mygameBinary_start功能,然後調用main,和你的遊戲開始。以這種方式

動態鏈接是必須支持以下內容:應用程序發佈

  • 庫更新後,它改變的功能和數據的位置。
  • 單個應用程序在不同版本的操作系統
  • 不確定性,其中庫或應用程序可以在存儲器
  • 加載通過共享由多個應用程序之間用於圖書館的物理RAM降低芯的大小運行。

一些操作系統的細節有所不同,例如OSX和AIX都將一些庫預裝入內存中的固定位置。這意味着他們不需要加載,只需鏈接,這可能會更快。

某些操作系統,如OSX和Linux有時支持預鏈接,這是一個腳本在啓動之前在系統上的應用程序上運行並執行鏈接的過程。當你啓動它們時,你不需要鏈接它們。這很重要,因爲在啓動應用程序時,鏈接會佔用大量的計算機時間,並且某些應用程序可能會在一秒鐘內多次啓動,如在應用程序構建過程中啓動gcc,,as,或者在索引計算機數據時過濾腳本(OSX Spotlight)。

6

鏈接是將一些較小的可執行文件作爲單個較大的可執行文件連接在一起的過程。

加載正在執行前將可執行文件加載到內存中。

+1

他問動態庫,其中案例鏈接不是將較小的「可執行文件」包含在較大的文件中的過程。 – tgamblin 2009-12-23 09:06:36

1

兩者都發生在動態庫的運行時。

首先,加載庫以及它們的所有依賴關係(以及這些庫的依賴關係等)。然後動態鏈接器解析加載庫中的符號。通常這兩個功能都是由同一個軟件實現的;在Linux上它是ld.so

靜態庫中的符號在鏈接時解析幷包含在可執行文件本身中。但是,靜態庫可能有動態庫在運行時滿足的未解析符號。

How to Write Shared Libraries中,有關於如何發生這種情況的詳細說明,如何對名稱進行散列,如何在運行時解析符號的費用等。

3

有兩種類型的鏈接:靜態鏈接和動態鏈接。

靜態鏈接發生在編譯時,因此它在加載程序之前發生。通過靜態鏈接,程序使用的外部符號(例如函數名稱)將在編譯時解析。

動態鏈接發生在運行時,所以它發生在加載程序之後或加載時。通過動態鏈接,符號在加載時或在符號被訪問(延遲綁定)時的運行時解析。後者更常見。

-1

Windows和Unix系統對動態庫使用完全不同的方法。

Windows DLL未鏈接。因此,您不能在DLL之間共享靜態對象。它就像您地址空間中的一個單獨的程序。

Unix共享對象在運行時確實「鏈接」,就像同一項目的不同模塊一樣,執行符號解析。

+0

不正確,Windows DLL鏈接並可共享數據。 – 2009-12-23 12:08:53

+0

nobugz:我建議你查找條目「鏈接」以及符號分辨率是如何工作的。你會明白爲什麼沒有辦法在DLL邊界上共享一個靜態變量。 – 2009-12-23 13:44:09

-1

動態鏈接和庫加載都在運行時發生,但動態鏈接在程序執行之前完成並由系統鏈接器完成。例如,如果所需的庫缺失,程序將無法執行。另一方面,圖書館加載是通過程序本身通過dlopen/LoadLibrary函數完成的。在這種情況下,加載過程由應用程序控制,例如可以處理錯誤。

+0

所以什麼時候加載發生然後?它在鏈接階段之前(在動態鏈接的情況下) – Vijay 2009-12-23 11:57:05

+0

在加載的情況下,當程序調用dlopen/LoadLibrary函數時加載庫。它可以發生,只要程序員想要;) – 2009-12-23 13:23:07

0

file01.c,file02.c - >產生 - > file01.o,file02.o - >這些.o信息被棍棒化並放入一個動態庫中,即lib1.a file11。 c,file12.c - >產生 - > file11.o,file12.o - >這些.o信息被棍棒化並放入單個動態庫中,即lib2.a

現在,我有2個最終鏈接在一起以生成可執行文件的庫(如.elf或.mot或.fls)。鏈接lib1.a和lib2.a中的信息以形成單個可執行文件的過程稱爲鏈接。

現在,我需要將其加載到內存中,以便運行它以查看最終可執行文件的行爲。將最終可執行文件(如.elf或.mot或.fls)加載到內存中以便運行的過程稱爲加載。

我希望這會清除鏈接和加載的重要性(但是定義不合適:-))。

+0

我知道鏈接和加載過程...我需要的是他們哪一個會先發生,爲什麼? – Vijay 2009-12-26 05:59:06

+0

這是肯定鏈接,首先發生......這給了我們最終的可執行文件...然後加載執行...所以先鏈接,然後加載... 順便說一下,對於延遲響應抱歉。 .. :-) – wrapperm 2009-12-28 07:26:05

相關問題