1. 程式人生 > >LIB和DLL的區別和使用

LIB和DLL的區別和使用

轉載:http://www.cppblog.com/amazon/archive/2009/09/04/95318.html

共有兩種庫: 一種是LIB包含了函式所在的DLL檔案和檔案中函式位置的資訊(入口),程式碼由執行時載入在程序空間中的DLL提供,稱為動態連結庫dynamic link library。 一種是LIB包含函式程式碼本身,在編譯時直接將程式碼加入程式當中,稱為靜態連結庫static link library。 共有兩種連結方式: 動態連結使用動態連結庫,允許可執行模組(.dll檔案或.exe檔案)僅包含在執行時定位DLL函式的可執行程式碼所需的資訊。 靜態連結使用靜態連結庫,連結器從靜態連結庫LIB獲取所有被引用函式,並將庫同程式碼一起放到可執行檔案中。 關於lib和dll的區別如下: (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需注意兩個檔案: (1).h標頭檔案,包含lib中說明輸出的類或符號原型或資料結構。應用程式呼叫lib時,需要將該檔案包含入應用程式的原始檔中。 (2).LIB檔案,略。 使用dll需注意三個檔案: (1).h標頭檔案,包含dll中說明輸出的類或符號原型或資料結構的.h檔案。應用程式呼叫dll時,需要將該檔案包含入應用程式的原始檔中。 (2).LIB檔案,是dll在編譯、連結成功之後生成的檔案,作用是當其他應用程式呼叫dll時,需要將該檔案引入應用程式,否則產生錯誤。如果不想用lib檔案或者沒有lib檔案,可以用WIN32 API函式LoadLibrary、GetProcAddress裝載。 (3).dll檔案,真正的可執行檔案,開發成功後的應用程式在釋出時,只需要有.exe檔案和.dll檔案,並不需要.lib檔案和.h標頭檔案。 使用lib的方法: 靜態lib中,一個lib檔案實際上是任意個obj檔案的集合,obj檔案是cpp檔案編譯生成的。在編譯這種靜態庫工程時,根本不會遇到連結錯誤;即使有錯,也只會在使用這個lib的EXT檔案或者DLL工程裡暴露出來。 在VC中新建一個static library型別的工程Lib,加入test.cpp檔案和test.h檔案(標頭檔案內包括函式宣告),然後編譯,就生成了Lib.lib檔案。 別的工程要使用這個lib有兩種方式: (1)在project->link->Object/Library Module中加入Lib.lib檔案(先查詢工程目錄,再查詢系統Lib目錄);或者在原始碼中加入指令#pragma comment(lib, “Lib.lib”)。 (2)將Lib.lib拷入工程所在目錄,或者執行檔案生成的目錄,或者系統Lib目錄中。 (3)加入相應的標頭檔案test.h。 使用DLL的方法: 使用動態連結中的lib,不是obj檔案的集合,即裡面不會有實際的實現,它只是提供動態連結到DLL所需要的資訊,這種lib可以在編譯一個DLL工程時由編譯器生成。 建立DLL工程的方法(略)。 (1)隱式連結 第一種方法是:通過project->link->Object/Library Module中加入.lib檔案(或者在原始碼中加入指令#pragma comment(lib, “Lib.lib”)),並將.dll檔案置入工程所在目錄,然後新增對應的.h標頭檔案。

#include "stdafx.h"#include "DLLSample.h"#pragma comment(lib, "DLLSample.lib")    //你也可以在專案屬性中設定庫的連結int main(){        TestDLL(123);   //dll中的函式,在DllSample.h中宣告        return(1);}

(2)顯式連結 需要函式指標和WIN32 API函式LoadLibrary、GetProcAddress裝載,使用這種載入方法,不需要.lib檔案和.h標頭檔案,只需要.dll檔案即可(將.dll檔案置入工程目錄中)。

#include <iostream>

#include <windows.h>         //使用函式和某些特殊變數typedef void (*DLLFunc)(int);int main(){        DLLFunc dllFunc;        HINSTANCE hInstLibrary = LoadLibrary("DLLSample.dll");        if (hInstLibrary == NULL)        {          FreeLibrary(hInstLibrary);        }        dllFunc = (DLLFunc)GetProcAddress(hInstLibrary, "TestDLL");
        if (dllFunc == NULL)        {          FreeLibrary(hInstLibrary);        }        dllFunc(123);        std::cin.get();        FreeLibrary(hInstLibrary);        return(1);}

LoadLibrary函式利用一個名稱作為引數,獲得DLL的例項(HINSTANCE型別是例項的控制代碼),通常呼叫該函式後需要檢視一下函式返回是否成功,如果不成功則返回NULL(控制代碼無效),此時呼叫函式FreeLibrary釋放DLL獲得的記憶體。 GetProcAddress函式利用DLL的控制代碼和函式的名稱作為引數,返回相應的函式指標,同時必須使用強轉;判斷函式指標是否為NULL,如果是則呼叫函式FreeLibrary釋放DLL獲得的記憶體。此後,可以使用函式指標來呼叫實際的函式。 最後要記得使用FreeLibrary函式釋放記憶體。 注意:應用程式如何找到DLL檔案? 使用LoadLibrary顯式連結,那麼在函式的引數中可以指定DLL檔案的完整路徑;如果不指定路徑,或者進行隱式連結,Windows將遵循下面的搜尋順序來定位DLL: (1)包含EXE檔案的目錄 (2)工程目錄 (3)Windows系統目錄 (4)Windows目錄 (5)列在Path環境變數中的一系列目錄