程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> [C++ Primer]靜態鏈接庫(lib)和動態鏈接庫(dll)的區別和使用

[C++ Primer]靜態鏈接庫(lib)和動態鏈接庫(dll)的區別和使用

編輯:C++入門知識

如果對Linux下靜態鏈接庫和動態鏈接庫感興趣,請狂點擊 -->你懂的
一,概念
        1)靜態鏈接庫就是你使用的.lib文件,庫中得代碼最後需要連接到你的可執行文件中去,所以靜態連接的可執行文件一般比較大一些。
         使用方法
  
                       1>  格式如:#pragma comment(lib,"XXX.lib")
                       2>  針對開發環境:
                                     1、如果使用VC,可以在Project Setting-->Link中加入你的靜態庫,也可以直接把該.lib文件加入到你的工程中
                                     2、如果使用Visual Studio,位置在 項目→配置屬性→連接器→輸入→附加依賴項 中加入.lib文件
         構造方法
                            在靜態庫情況下,函數和數據被編譯進一個二進制文件(通常擴展名為*.lib),Visual C++的編譯器在鏈接過程中將從靜態庫中恢復這些函數和數據並把他們和應用程序中的其他模塊組合在一起生成可執行文件。這個過程稱為"靜態鏈接",此時因為應用程序所需的全部內容都是從庫中復制了出來,所以靜態庫本身並不需要與可執行文件一起發行。
               編程使用:使用lib需注意兩個文件:
                       (1).h頭文件,包含lib中說明輸出的類或符號原型或數據結構。應用程序調用lib時,需要將該文件包含入應用程序的源文件中。
                       (2).lib文件,見上面。
         2)Dynamic Link Library 的縮寫形式,DLL是一個包含可由多個程序同時使用的代碼和數據的庫,DLL不是可執行文件。動態鏈接提供了一種方法,使進程可以調用不屬於其可執行代碼的函數。函數的可執行代碼位於一個 DLL 中,該 DLL 包含一個或多個已被編譯、鏈接並與使用它們的進程分開存儲的函數。DLL 還有助於共享數據和資源。多個應用程序可同時訪問內存中單個DLL 副本的內容。DLL 是一個包含可由多個程序同時使用的代碼和數據的庫。
               DLL舉例
                               ActiveX 控件(.ocx) 文件: 示例是日歷控件,它使您可以從日歷中選擇日期。 ·
                              控制面板(.cpl) 文件 :cpl 文件的一個示例是位於控制面板中的項。每個項都是一個專用 DLL。
  ·                     設備驅動(.drv) 文件
                編程使用;
                           使用dll需注意三個文件:
                                     (1).h頭文件,包含dll中說明輸出的類或符號原型或數據結構的.h文件。應用程序調用dll時,需要將該文件包含入應用程序的源文件中。
                                     (2).LIB文件,是dll在編譯、鏈接成功之後生成的文件,作用是當其他應用程序調用dll時,需要將該文件引入應用程序,否則產生錯誤。如果不想用lib文件或者沒有lib文件,可以用WIN32 API函數LoadLibrary、GetProcAddress裝載。
                                    (3).dll文件,真正的可執行文件,開發成功後的應用程序在發布時,只需要有.exe文件和.dll文件,並不需要.lib文件和.h頭文件。
二,初步認識

               共有兩種庫:
                             一種是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的方法:
                     靜態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頭文件。
[html] 
#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文件置入工程目錄中)。
[html] 
#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環境變量中的一系列目錄


作者:tianshuai11

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved