一、基本定義。
通常,動態連結程式庫不直接執行,也不接收訊息。他們是一些獨立的檔案,包含能被程式或其他DLL調用來完成一定作業的函數。只有在被其他模組調用時,才會起作用。
所謂“動態連結”是指windows把一個模組中的函數調用連結到庫模組中的實際函數上的過程,發生在運行時刻。
有些動態連結程式庫是純資源,只包含資料,不包含代碼。
動態連結程式庫的標準副檔名 DLL,但也有其他副檔名,如EXE,FON,DRV等。但只有DLL才會被WINDOWS自動載入,其他的需要程式顯式的調用LoadLibrary或LoadLibraryEx來載入。
目標庫,lib格式,在用連結程式進行靜態連結時,它的代碼會自動加到程式的EXE檔案中。
輸入庫,lib格式,不包含代碼,而是為連結程式提供資訊,用來確定來源程式代碼中的函數調用。
目標庫和輸入庫在程式開發期間使用,靜態連結。動態連結程式庫在程式運行期間使用,動態連結。
多個進程調用同一個DLL時,每個進程都為DLL分配了自己的地址空間,DLL為每個進程儲存的資料不同。但可以用共用記憶體。
動態連結程式庫不接受訊息,但可以調用GetMessage和PeekMessage。
因為模態對話方塊的訊息是在程式的訊息迴圈之外接收到的,所以使用者可以在庫中建立模態對話方塊。
二、DLL簡單格式:
/*----------------------
EDRLIB.H header file
----------------------*/
#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif
EXPORT BOOL CALLBACK EdrCenterTextA (HDC, PRECT, PCSTR) ;
EXPORT BOOL CALLBACK EdrCenterTextW (HDC, PRECT, PCWSTR) ;
#ifdef UNICODE
#define EdrCenterText EdrCenterTextW
#else
#define EdrCenterText EdrCenterTextA
#endif
/*-------------------------------------------------
EDRLIB.C -- Easy Drawing Routine Library module
(c) Charles Petzold, 1998
-------------------------------------------------*/
#include <windows.h>
#include "edrlib.h"
int WINAPI DllMain (HINSTANCE hModule, DWORD fdwReason, PVOID pvReserved)
{
hInstance = hModule;
switch( dwReason )
{
case DLL_PROCESS_ATTACH: // The DLL is being mapped into the
// process's address space
DisableThreadLibraryCalls( hModule );
// This tells the system we don't want
// DLL_THREAD_ATTACH and DLL_THREAD_DETACH
// modifications sent to the specified
// DLL's DllMain function
break;
case DLL_PROCESS_DETACH: // The DLL is being unmapped from the
// process address space
break;
case DLL_THREAD_ATTACH: // A thread is being created
break;
case DLL_THREAD_DETACH: // A thread is exiting cleanly
break;
default:
break;
}
return TRUE ;//TRUE表示初始化成功
}
EXPORT BOOL CALLBACK EdrCenterTextA (HDC hdc, PRECT prc, PCSTR pString)
{
//。。。。do
}
EXPORT BOOL CALLBACK EdrCenterTextW (HDC hdc, PRECT prc, PCWSTR pString)
{
//。。。。do
}
支援Unicode和非Unicode
DllMain//入口函數,初次開機庫和結束庫時調用,用於執行初始化和未初始化。
EXPORT//標識匯出函數。用來把函數名添加到.lib檔案中
#define EXPORT extern "C" __declspec (dllexport)//支援C和C++
三、DLL共用記憶體,啟動多次DLL,但這段記憶體共用。
#pragma data_seg ("shared")
int iTotal = 0 ;
WCHAR szStrings [MAX_STRINGS][MAX_LENGTH + 1] = { '\0' } ;
#pragma data_seg ()
#pragma comment(linker,"/SECTION:shared,RWS")////指示名為shared的記憶體段,可讀可寫共用。等同與在工程屬性中設定:/SECTION:shared,RWS
四、不用輸入的動態連結程式庫:
HMODULE LoadLibrary( LPCTSTR lpFileName // file name of module);
FARPROC GetProcAddress( HMODULE hModule, // handle to DLL module LPCSTR lpProcName // function name);
BOOL FreeLibrary( HMODULE hModule // handle to DLL module);
五、純資源DLL。
DLL裡面就一個DLLMAIN return true;在資源裡面添加資源即可。
調用的時候,以BITMAP為例:
hLibrary = LoadLibrary (TEXT ("BITLIB.DLL"))
hBitmap = LoadBitmap (hLibrary, MAKEINTRESOURCE ("BITMAP1")) ;
FreeLibrary (hLibrary) ;