[英]What is the difference between '\0' and '\n' in the C programming language?
[英]what is the difference between linking and loading in c language
鏈接和加載動態庫是否都在運行時發生? 或者只是在運行時加載庫?
請參閱前面關於靜態鏈接和動態鏈接之間區別的非常好的觀點。 假設您指的是動態鏈接,那么:
加載和(動態)鏈接都是由鏈接器完成的 - 在linux和其他Unix上/lib/ld.so
,這是由/lib/ld.so
完成的,這是幾乎所有情況下操作系統啟動的實際程序。 ld.so
反過來將你的應用程序 - mygameBinary
加載到內存中,然后ld.so
從文件mygameBinary
讀取它需要的動態鏈接庫列表。
然后,鏈接器ld.so
依次將每個庫加載到內存中,例如libc.so
, libpthread.so
, libopengl.so
,並查看這些可能需要的其他庫,例如libm.so
加載完成后,開始鏈接 ,查看由一個庫或應用程序導出並由另一個庫或應用程序導入的命名對象或函數的過程。 然后,鏈接器更改各種引用,有時還會更新代碼以更新每個庫中的未鏈接數據指針和函數調用,以指向實際數據或函數所在的位置。 例如, mygameBinary
對printf
的mygameBinary
開始沒有指向任何內容(實際上它只是調用鏈接器),但是在鏈接之后變成了跳轉到libc
的printf
函數。
完成此鏈接后,通過調用mygameBinary
的_start
函數啟動應用程序,然后調用main
,然后啟動游戲。
以這種方式動態鏈接是必要的,以支持以下內容:
某些操作系統的細節不同,例如OSX和AIX都將某組庫預先加載到內存中的固定位置。 這意味着它們不需要加載,只需鏈接,這可能更快。
某些操作系統(如OSX,有時還支持Linux)支持預鏈接,這是一個腳本在啟動它們之前在系統上的應用程序上運行並進行鏈接的過程。 啟動它們時,您無需鏈接它們。 這很重要,因為聯需要,當你啟動應用了大量的計算機的時間,和一些應用程序可能會推出多次第二,如gcc
, cpp
和as
在應用程序的構建過程,或過濾器腳本索引你的計算機的數據時(OSX Spotlight)。
鏈接是獲取一些較小的可執行文件並將它們作為單個較大的可執行文件連接在一起的過程。
加載是在執行之前將可執行文件加載到內存中。
有兩種類型的鏈接:靜態鏈接和動態鏈接。
靜態鏈接在編譯時發生,因此它在加載程序之前發生。 使用靜態鏈接,程序使用的外部符號(例如函數名稱)將在編譯時解析。
動態鏈接在運行時發生,因此它發生在加載程序之后或加載時。 通過動態鏈接,符號在加載時或在訪問符號時的運行時解析(延遲綁定)。 后者更常見。
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)加載到內存中以便運行的過程稱為加載。
我希望這將清除鏈接和加載的重要性(但定義不合適:-))。
Windows和Unix系統使用完全不同的動態庫方法。
Windows DLL未鏈接。 因此,您無法跨DLL共享靜態對象。 它就像你的地址空間中的一個單獨的程序。
Unix共享對象在運行時實際上是“鏈接”的,就像同一項目的不同模塊一樣,執行符號解析。
動態鏈接和庫加載都在運行時發生,但動態鏈接在程序執行之前完成,由系統鏈接器完成。 因此,例如,如果缺少必需的庫,則無法執行程序。 另一方面,庫加載是由程序本身通過dlopen / LoadLibrary函數完成的。 在這種情況下,加載過程由應用程序控制,該應用程序可以例如處理錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.