📄 19.8 dllmain函数.txt
字号:
19.8 DIIMain函数
在编写 DLL程序时,还有一个比较重要的函数: DllMain。通过前面的介绍,我们知道,对可执行模块来说,其入口函数是 WinMain。而对 DLL来说,其入口函数是 DlIMain,但该函数是可选的。也就是说,在编写 DLL程序时,可以提供也可以不提供DlIMain函数。如果提供了 DllMain函数,那么当系统加载该 DLL时,就会调用该函数。 DlIMain函数的原型声明如下所示:
BOOL W工 NAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason , LPVO工 D 1pvReserved) ;
可见, DlIMain函数有三个参数,其含义分别如下所述:
. hinstDLL
动态链接库模块的句柄。当 DLL初次被加载时,它的句柄会通过此参数传递进来。就好像 WinMain函数有一个当前实例句柄参数一样。因此,在编写 DLL程序时,如果某些函数需要用到当前 DLL模块的句柄,那么就可以为该 DLL提供 DllMain函数,然后将通过参数 hinstDLL传递进来的模块句柄保存到一个全局变量中,供其他函数使用。
. fdwReason
一个标记值,用来指示调用该 DLL入口函数的原因。该参数的取值是表 19.2中所列值之一。
表 19.2 fdwReason参数取值
取值DLL PROCESS ATIACH DLL THREAD ATIACH DLL_THREAD_DETACH DLL]ROCESS_DETACH 说明 进程第一次加载 DLL并调用 DI lM ain函数 当前进程正创建一个新线程 线程结束 进程结束
因此,在编写 DLL程序时,如果提供了 DllMain函数,在此函数中就可以利用 switc h/case语句,对调用该 DLL的每种情况进行判断,并分别加以处理。
. lpvReserved
保留参数。不需要关心此参数,但可以检测这个指针值,如果 DLL被动态加载,则
,
730 I胁"
vc..深λ详解
此参数值为NULL;如果是静态加载,则此参数值为非NULL。
读者应注意,如果提供了DllMain函数,那么在此函数中不要进行太复杂的调用。因为在加载该动态链接库时,可能还有一些核心动态链接库没有被加载。例如,我们自己编写的某个DLL被加载时, user32.dll或GDI32.dll这两个核心动态链接库还没有被加载。前面的内容已经介绍了,程序在运行时,加载程序会依次加载该进程需要的DLL。而我们自己编写的DLL可能会比较靠前地被加载。如果自己编写的DlIMain函数需要调用这两个核心DLL中的某些函数的话,这时就会失败,从而导致程序终止。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -