1. 程式人生 > >c++動態庫封裝及調用(1、動態庫介紹)

c++動態庫封裝及調用(1、動態庫介紹)

oca 新版本 指令 二進制 運行時 失去 理論 load 程序

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、動態庫介紹)