一、基本定义。
通常,动态链接库不直接执行,也不接收消息。他们是一些独立的文件,包含能被程序或其他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) ;