兩種庫:
動態連接庫(dynamic link library),代碼由運行時加載在程序空間中的DLL提供。
靜態連接庫(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和lib必須隨應用程序一塊兒發行,不然會產生錯誤。若是不想用lib文件或者沒有lib文件,能夠用win32 API函數LoadLibrary、GetProcAddress裝載。
使用lib須要注意:
.h文件,包含lib中說明輸出的類或符號原型或數據結構的.h文件。應用程序調用dll時,須要將該文件包含入應用程序的源文件中。
.lib文件
使用dll須要注意:
.h文件,包含dll中說明輸出的類或符號原型或數據結構的.h文件。應用程序調用dll時,須要將該文件包含入應用程序的源文件中。
.lib文件
.dll文件
使用lib的方法:
靜態lib中,一個lib文件其實是任意個obj文件的集合,obj文件是cpp文件編譯生成的。在編譯這種靜態庫工程時,根本不會遇到連接錯誤;即便有錯,也只會在使用這個lib的ext文件或者dll工程中暴露出來。
在VC中新建一個static library類型的工程Lib,加入test.cpp文件和test.h文件(頭文件內包括函數聲明),而後編譯,就生成了Lib.lib文件。
別的工程要使用這個lib有兩種方式:
(1)在工程右鍵->屬性->連接器->輸入->附加依賴項中加入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環境變量中的一系列目錄