windows下LIB和DLL的區別與使用

來源:互聯網
上載者:User

共有兩種庫:
一種是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/LibraryModule中加入.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環境變數中的一系列目錄


來自:http://www.cppblog.com/amazon/archive/2009/09/04/95318.html


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.