每个DLL都可以有一个入口点函数DllMain,系统会在不同的时刻调用此函数。以下是DllMain的一般形式:

BOOL WINAPI DllMain(
HINSTANCE hinstDLL,  // handle to DLL module
DWORD fdwReason,     // reason for calling function
LPVOID lpReserved )  // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE;  // Successful DLL_PROCESS_ATTACH.
}
以上代码摘自MSDN,几乎所有的DllMain都以这种形式呈现。
先来看一下这个函数传递进来的参数:
1、 HINSTANCE hinstDLL
这个参数是该DLL实例的句柄,也就是此DLL映射到进程地址空间后,在该进程地址空间中的位置。
2、 DWORD fdwReason
此参数标示了调用DllMain函数的原因。有四种值,就是函数中case后的取值。各个取值的含义,稍后论述。
3、 LPVOID lpReserved 
保留。
现在我们来讨论一下fdwReason的四种取值,这些取值,也直接反映了操作系统会在何种情况下调用DllMain。
1、DLL_PROCESS_ATTACH
当系统第一次将一个DLL映射到进程地址空间中时,会调用DllMain,并为fdwReason传入DLL_PROCESS_ATTACH。
注意,只有在第一次映射的时候,才会这样。如之后,另一线程再次显式加载此DLL,则操作系统只是增加该DLL的使用计数,而不会再次使用DLL_PROCESS_ATTACH来调用DllMain。
对DLL_PROCESS_ATTACH的处理,代表了DLL的初始化。
DllMain的返回值,也是针对DLL_PROCESS_ATTACH消息的。对于其余的三种取值,不起作用。
对于隐式加载,如DllMain返回FALSE,则程序会启动失败。对于显式加载,则会使LoadLibrary返回NULL。
2、DLL_PROCESS_DETACH
当系统将一个DLL从进程地址空间中撤销映射时,则会向DllMain传入DLL_PROCESS_DETACH。我们应当在此处放置一些清理代码。
当使用FreeLibrary时,如该线程的使用计数为0时,操作系统才会使用DLL_PROCESS_DETACH来调用DllMain。如使用计数大于0,则只是单纯的减少该DLL的计数。
3、DLL_THREAD_ATTACH
当进程创建一个线程,则系统会检查当前已映射到该进程空间中的所有DLL映像,并用DLL_THREAD_ATTACH来调用每个DLL的DllMain。
只有当所有DLL都完成了对DLL_THREAD_ATTACH的处理后,新线程才会执行它的线程函数。
另外,主线程不可能用DLL_THREAD_ATTACH来调用DllMain,因为主线程必然是在进程初始化的时候,用DLL_PROCESS_ATTACH调用DllMain的。
4、DLL_THREAD_DETACH
线程若要终止,会调用ExitThread,但是此函数不会立即终止线程,而是会利用DLL_THREAD_DETACH来调用当前进程地址空间中的所有DLL镜像的DllMain.
当每个DLL的DllMain都处理完后,系统才会真正的结束线程。
最后看一下DllMain的序列化调用
举个例子:
进程中有两个线程,A与B。进程的地址空间中,映射了一个名为SomeDll.dll的DLL。两个线程都准备通过CreateThread来创建另两个线程,C和D。
当线程A调用CreateThread来创建线程C的时候,系统会用DLL_THREAD_ATTACH来调用SomeDll.dll的DllMain,当线程C执行其中代码的时候,线程B调用CreateThread来创建线程D。
这时,系统同样会用DLL_THREAD_ATTACH来调用SomeDll.dll的DllMain,这次是让线程D来执行其中的代码。
但是此时,系统会对DllMain执行序列化,它会将线程D挂起,直至线程C执行完DllMain中的代码返回为止。
当C线程执行完DllMain中的代码并返回时,可以继续执行C的线程函数。此时,系统会唤醒线程D,让D执行DllMain中的代码。当返回后,线程D开始执行线程函数。

DLL入口点函数DllMain .相关推荐

  1. DLL入口点函数DllMain

     每个DLL都可以有一个入口点函数DllMain,系统会在不同的时刻调用此函数.以下是DllMain的一般形式: BOOL WINAPI DllMain(HINSTANCE hinstDLL, / ...

  2. Dll入口函数参数详解

    DLL程序入口点函数:DllMain,注意:大小写是区别的(仅导出资源的DLL可以没有DllMain函数). 函数原型: BOOL APIENTRY DllMain( HMODULE hModule, ...

  3. Windows应用程序类型和相应的入口点函数

    Windows应用程序类型和相应的入口点函数,Windows编程真难啊.. 来源:大神的书 Windows核心编程 第五版

  4. illustrator插件开发-AI插件-aip格式-第一章 第二小节 入口点函数

    文章目录 1.入口点函数 2.作者答疑 1.入口点函数   插件作为illustrator软件的一部分,需要与主体程序进行通信,必然需要约定调用函数.而入口点函数就是其中关键一环,实例代码如下: /* ...

  5. windows DLL的入口函数DllMain【学习笔记】

    文档有详细介绍 入口函数可能会被调用多次 实例代码1:判断两种情况 实例代码2:判断三种情况 实例代码3:判断四种情况 exe的Mian与Dll的DllMain 入口函数的区别 1.MIan只执行一次 ...

  6. vs 创建win32 dll(带有DllMain函数)项目时遇到的一系列问题

    好久没有写win32 的dll 了,之前一直用带窗体的mfc dll(方面测试嘛-毕竟),搞得现在忘了正经的dll怎么写了,没办法,在这里总结下,防止以后再忘.(以后肯定忘,可能我明天就忘了 哈哈哈) ...

  7. android的应用入口点函数,android 没有main函数,怎么找到程序执行入口呢?以及activity主要生命周期的方法说明...

    android应用程序,由一到多个Activity组成.每个Activity没有很紧密的联系,因为我们可以在自己的程序中调用其它Activity,特别是调用自己的代码之外生成的Activity,比如a ...

  8. 什么是动态链接库(DLL)以及常见问题

    概要 本文说明什么是动态链接库 (DLL) 以及在使用 DLL 时可能发生的各种问题. 然后,本文说明在开发您自己的 DLL 时应该考虑的一些高级问题.在说明什么是 DLL 的过程中,本文将说明动态链 ...

  9. [Win32] DLL的开发和使用

    本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article ...

最新文章

  1. 高校开学需要重新分配宿舍!国家卫健委和教育部发布重要通知
  2. CAXA电子图板2020中文版
  3. 检查邮箱是否包含教育后缀.edu结尾的邮箱
  4. Throwable 结构图
  5. 那些年,我们处理过的SQL问题
  6. Docker 基础与实战,看这一篇就够了
  7. mysql 查询的关键词的执行顺序
  8. Android解决滑动冲突
  9. CKEditor 4.x 批量图片上传插件
  10. 分享Photoshop脚本代码_压缩,图片置灰,切图导出等
  11. 微信小程序——从后台获取数据库数据并在前台显示(前端+后端+数据库)
  12. java-opencv拍照(可自定义分辨率)
  13. 九龙证券|重大利好,这板块全线大涨!
  14. 危机管理应遵循哪些原则?
  15. matlab 复数函数拟合,lsqcurvefit拟合结果为复数
  16. 【电商项目实战】个人资料(详细篇)
  17. 力软新版APP:聊一聊Uni-App框架,跨平台多端解决方案
  18. 基于层次分析法的轴间预瞄和轴距预瞄俯仰半车LQR控制仿真分析(重型汽车)
  19. railgun报文层级
  20. 【python】你的连连看为啥子如此之快,原来你开全自动了呀!!

热门文章

  1. 开源一个IDA小插件:修复VMP dump导入函数
  2. 教你使用 Python 获取美国重要经济指标数据
  3. Windows安装Weblogic
  4. Django 2.1.3 模型层 模型
  5. BMP编程实践1:C语言实现bmp位图分析与创建
  6. (2)3DMAX之基础对象创建
  7. 模式识别:最小错误率贝叶斯决策分类
  8. 如何掌握PMO核心技能和知识?
  9. 【Proteus仿真】【51单片机】PM2.5空气质量监测系统设计
  10. Matlab二维热传导方程求解