標籤:開始 執行檔案 crt 區別 處理 資源 adl 動態 相同
1、一個程式從源檔案編譯產生可執行檔的步驟:
先行編譯 --> 編譯 --> 彙編 --> 連結
(1)先行編譯,即預先處理,主要處理在原始碼檔案中以“#”開始的先行編譯指令,如宏展開、處理條件編譯指令、處理#include指令等。
(2)編譯過程就是把預先處理完的檔案進行一系列詞法分析、文法分析、語義分析以及最佳化後產生相應的彙編代碼檔案。
(3)彙編是將彙編代碼轉變成二進位檔案。
(4)連結將二進位檔案連結成一個可執行檔命令,主要是把分散的資料和代碼收集併合成一個單一的可載入並可執行檔的檔案。連結可以發生在代碼靜態編譯、程式被載入時以及程式執行時。連結過程的主要工作是符號解析和重定位。
2、庫
庫是一組目標檔案的包,就是一些最常用的代碼編譯成目標檔案後打包存放。而最常見的庫就是執行階段程式庫(Runtime Library),如C運行庫CRT.
庫一般分為兩種:靜態庫(.a 、.lib)動態庫(.so 、.dll )所謂靜態、動態是指連結過程。
3、靜態庫與動態庫
區別:
(1)lib是編譯時間用到的,dll是運行時用到的。如果要完成原始碼的編譯,只需要lib;如果要使動態連結的程式運行起來,只需要dll。
(2)如果有dll檔案,那麼lib一般是一些索引資訊,記錄了dll中函數的入口和位置,dll中是函數的具體內容;如果只有lib檔案,那麼這個lib檔案是靜態編譯出來的,索引和實現都在其中。使用靜態編譯的lib檔案,在運行程式時不需要再掛動態庫,缺點是導致應用程式比較大,而且失去了動態庫的靈活性,發布新版本時要發布新的應用程式才行。
(3)動態連結的情況下,有兩個檔案:一個是LIB檔案,一個是DLL檔案。LIB包含被DLL匯出的函數名稱和位置,DLL包含實際的函數和資料,應用程式使用LIB檔案連結到DLL檔案。在應用程式的可執行檔中,存放的不是被調用的函數代碼,而是DLL中相應函數代碼的地址,從而節省了記憶體資源。DLL和LIB檔案必須隨應用程式一起發行,否則應用程式會產生錯誤。如果不想用lib檔案或者沒有lib檔案,可以用WIN32 API函數LoadLibrary、GetProcAddress裝載。
------這裡主要講動態庫的優點特性。--------
靜態庫:函數和資料被編譯進一個二進位檔案(通常副檔名為.LIB)。在使用靜態庫的情況下,在編譯連結可執行檔時,連結器從庫中複製這些函數和資料並把它們和應用程式的其它模組組合起來建立最終的可執行檔(.EXE檔案)。
在使用動態庫的時候,往往提供兩個檔案:一個引入庫和一個DLL。引入庫包含被DLL匯出的函數和變數的符號名,DLL包含實際的函數和資料。在編譯連結可執行檔時,只需要連結引入庫,DLL中的函數代碼和資料並不複製到可執行檔中,在啟動並執行時候,再去載入DLL,訪問DLL中匯出的函數。
靜態庫有兩個重大缺點:
1)空間浪費
2)靜態連結對程式的更新、部署和發布會帶來很多麻煩。一旦程式中有任何模組更新,整個程式就要重新連結,發布給使用者。
動態連結的基本思想:把程式按照模組拆分成各個相對獨立的部分,在程式運行時才將它們連結在一起形成一個完整的程式,而不是想靜態連結一樣把所有的程式模組都連結成一個單獨的可執行檔。
特點:
1)代碼共用,所有引用該動態庫的可執行目標檔案共用一份相同的代碼與資料。
2)程式升級方便,應用程式不需要重新連結新版本的動態庫來升級,理論上只要簡單地將舊的目標檔案覆蓋掉。
3)在運行時可以動態地選擇載入各種應用程式模組
c++動態庫封裝及調用(1、動態庫介紹)