天天看點

靜态連結庫LIB和動态連結庫DLL靜态連結庫LIB和動态連結庫DLL

靜态連結庫LIB和動态連結庫DLL

靜态連結庫與動态連結庫都是共享代碼的方式,如果采用靜态連結庫,則無論你願不願意,lib 中的指令都全部被直接包含在最終生成的 EXE 檔案中了。但是若使用 DLL,該 DLL 不必被包含在最終 EXE 檔案中,EXE 檔案執行時可以“動态”地引用和解除安裝這個與 EXE 獨立的 DLL 檔案。靜态連結庫和動态連結庫的另外一個差別在于靜态連結庫中不能再包含其他的動态連結庫或者靜态庫,而在動态連結庫中還可以再包含其他的動态或靜态連結庫。動态庫就是在需要調用其中的函數時,根據函數映射表找到該函數然後調入堆棧執行。如果在目前工程中有多處對dll檔案中同一個函數的調用,那麼執行時,這個函數隻會留下一份拷貝。但是如果有多處對lib檔案中同一個函數的調用,那麼執行時,該函數将在目前程式的執行空間裡留下多份拷貝,而且是一處調用就産生一份拷貝。

靜态庫是一個或者多個obj檔案的打包,是以有人幹脆把從obj檔案生成lib的過程稱為Archive,即合并到一起。比如你連結一個靜态庫,如果其中有錯,它會準确的找到是哪個obj有錯,即靜态lib隻是殼子。

動态庫一般會有對應的導入庫,友善程式靜态載入動态連結庫,否則你可能就需要自己LoadLibary調入DLL檔案,然後再手工GetProcAddress獲得對應函數了。有了導入庫,你隻需要連結導入庫後按照頭檔案函數接口的聲明調用函數就可以了。

這也是實際上很多開源代碼釋出的慣用方式:

1、 預編譯的開發包:包含一些.dll檔案和一些.lib檔案。其中這裡的.lib就是導入庫,而不要錯以為是靜态庫。但是引入方式和靜态庫一樣,要在連結路徑上添加找到這些.lib的路徑。而.dll則最好放到最後産生的應用程式exe執行檔案相同的目錄。這樣運作時,就會自動調入動态連結庫。

Ø 對于DLL的導出,可以采用如下方法:

#ifdef WLL_EXPORTS

#define WLL_API __declspec(dllexport)

#else

#define WLL_API __declspec(dllimport)

#endif
           

這是導出類的宏定義,将導出類必須加上該宏,才能被導出。

此處的WLL_EXPORTS會出現在 projectàsettingsàC++à PreProcessor的PreProcessor definition中,這個MACRO表明其要定義一個導出宏。

目前庫編譯時,加了WLL_API的類将被導出,而包含該頭檔案的其他調用DLL或EXE,由于沒有定義WLL_API宏,将申明為導入該類。

Ø 動态庫函數的調用,可以采用靜态連結的方式,主要步驟如下:

1) 包含DLL中導出的頭檔案。

2) 采用#pragma comment(lib,”..//debug//libTest.lib”)導入動态庫生成的*.lib頭檔案。或在projectàsettingsàLinkeràInput的Additional Dependencies中加入lib檔案。

3) 将動态庫生成的*.dll檔案放到EXE或DLL的同一目錄下。

Ø 也可以采用動态加載的方式調用,步驟Another.dll有一個int Add(int x,int y) 函數。則完整的調用過程如下:

typedef int (* FunPtr)(int,int);          //定義函數指針

FunPtr funPtr;

Handle handle =LoadLibrary("Another.dll");

funPtr =(FunPtr)GetProcAddress(handle ,"Add");

funPtr(,);                         // 2+3;

FreeLibrary(handle);         // 釋放載入的動态庫 使用者自己編譯:下載下傳的是源代碼,按照readme自己編譯。生成很可能也是.dll + .lib(導入庫)的庫檔案
           

3、 如果你隻有dll,并且你知道dll中函數的函數原型,那麼你可以直接在自己程式中使用LoadLibary調入DLL檔案,GetProcAddress擷取函數位址,然後調用。

1、 靜态連結庫(比較簡單):

首先,靜态連結庫的使用需要庫的開發者提供生成庫的.h頭檔案和.lib檔案。生成庫的.h頭檔案中的聲明格式如下:

extern “C” 函數傳回類型 函數名(參數表);

在調用程式的.cpp源代碼檔案中如下:

#include "../lib.h"

#pragma comment(lib,"..//debug//libTest.lib")      //指定與靜态庫一起連結
           

其次因為靜态連結庫是将全部指令都包含入調用程式生成的EXE檔案中。是以如果用的是靜态連結庫,那麼也就不存在“導出某個函數提供給使用者使用”的情況,要想用就得全要!要不就都别要!

2、 态連結庫:

動态連結庫的使用需要庫的開發者提供生成的.lib檔案和.dll檔案。或者隻提供dll檔案。

首先我們必須先注意到DLL内的函數分為兩種:

1) 出函數,可供應用程式調用;

2) LL内部函數,隻能在 DLL 程式使用,應用程式無法調用它們。若想調用DLL中的某個函數就要以某種形式或方式指明它到底想調用哪一個函數。

繼續閱讀