[普通]DLL_PROCESS_ATTACH通知

作者(passion) 阅读(1009次) 评论(0) 分类( 软件)

当DLL被初次映射到进程的地址空间中时,系统将调用该DLL的DllMain函数,给它传递参数fdwReason的值DLL_PROCESS_ATTACH。只有当DLL的文件映像初次被映射时,才会出现这种情况。如果线程在后来为已经映射到进程的地址空间中的DLL调用LoadLibrary(Ex)函数,那么操作系统只是递增DLL的使用计数,它并不再次用DLL_PROCESS_ATTACH的值来调用DLL的DllMain函数。

当处理DLL_PROCESS_ATTACH时,DLL应该执行DLL中的函数要求的任何与进程相关的初始化。例如,DLL可能包含需要使用它们自己的堆栈(在进程的地址空间中创建)的函数。通过在处理DLL_PROCESS_ATTACH通知时调用HeapCreate函数,该DLL的DllMain函数就能够创建这个堆栈。已经创建的堆栈的句柄可以保存在DLL函数有权访问的一个全局变量中。

当DllMain处理一个DLL_PROCESS_ATTACH通知时,DllMain的返回值能够指明DLL的初始化是否已经取得成功。如果对HeapCreate的调用取得了成功,DllMain应该返回TRUE。如果堆栈不能创建,它应该返回FALSE。如果fdwReason使用的是其他的值,即DLL_PROCESS_DETACH、DLL_THREAD_ATTACH和DLL_THREAD_DETACH,那么系统将忽略DllMain返回的值。

当然,系统中的有些线程必须负责执行DllMain函数中的代码。当一个新线程创建时,系统将分配进程的地址空间,然后将.exe文件映像和所有需要的DLL文件映像映射到进程的地址空间中。然后它创建进程的主线程,并使用该线程调用每个DLL的带有DLL_PROCESS_ATTACH值的DllMain函数。当已经映射的所有DLL都对通知信息作出响应后,系统将使进程的主线程开始执行可执行模块的C/C++运行期启动代码,然后执行可执行模块的进入点函数(main、wmain、WinMain或wWinMain)。如果DLL的任何一个DllMain函数返回FALSE,指明初始化没有取得成功,系统便终止整个进程的运行,从它的地址空间中删除所有文件映像,给用户显示一个消息框,说明进程无法启动运行。

下面让我们来看一看DLL被显式加载时的情况。当进程中的一个线程调用LoadLibrary(Ex)时,系统会找出特定的DLL,并将它映射到进程的地址空间中。然后,系统使用调用LoadLibrary(Ex)的线程,调用DLL的带有DLL_PROCESS_ATTACH值的DllMain函数。当DLL的DllMain函数处理了通知消息后,系统便允许调用的LoadLibrary(Ex)函数返回,同时该线程像平常一样继续进行处理。如果DllMain函数返回FALSE,指明初始化没有取得成功,那么系统就自动从进程的地址空间中卸载DLL的文件映像,而对LoadLibrary(Ex)的调用则返回NULL。


« 上一篇:wifi共享上网(至尊版wifi)
« 下一篇:ASP.NET附加数据库文件的方式,如何发布到IIS7而不导致SQLServer出错
在这里写下您精彩的评论
  • 微信

  • QQ

  • 支付宝

返回首页
返回首页 img
返回顶部~
返回顶部 img