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

BOOL WINAPI DllMain(HINSTANCE hinstDLL,  // handle to DLL moduleDWORD fdwReason,     // reason for calling functionLPVOID 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. vue pc端 商品轮播图_轮播图高点击商品图
  2. 计算机技术+智能化水电站,水电工程BIM用太少?水电工程BIM案例全解读
  3. Java Nested Classes(内部类~第一篇英文技术文档翻译)
  4. 宁波计算机程序32届初赛,25届宁波市中小学计算机程序设计竞赛初赛试题
  5. IE7、IE8、IE9、IE10后各版本的更新及差别
  6. 妙用chrome插件,实现U校园自动填答案
  7. 时间管理工具推荐,助你实现高效能,慢生活
  8. 神州数码交换机配置基本命令
  9. ubuntu wine qq
  10. easypoi 实现多sheet导出excel
  11. 牛客刷题:放苹果(编程题)
  12. 普鸥知产|亚马逊品牌备案被判“滥用行为”无法备案如何解决?
  13. access团员人数公式_2015年3月全国二级ACCESS操作真题第1套
  14. 安装PS出现“由于找不到VCRUNTIME 140_1.dll”的解决方法
  15. getopt.h及相应的函数
  16. Android WiFi开发 (一)扫描、连接、信息
  17. poj 3186 Treats for the Cows (区间dp)
  18. python怎么定义int变量_Python 变量类型 | 菜鸟教程
  19. 电商项目之购物车设计
  20. 实验10-9 十进制转换二进制 (15分)

热门文章

  1. 天涯明夜刀手游微信第一服务器,天涯明月刀手游微信哪个区人多 微信一区选哪个好[多图]...
  2. java手工注入bean_java相关:Spring中如何动态注入Bean实例教程
  3. 06512oracle数据库,ORA-06512 – 专业Oracle数据库恢复,或许是您恢复数据的最后机会@phone:13429648788 - 专业Oracle数据库恢复技术支持...
  4. java技术论坛的毕业设计_基于java的bbs论坛设计,软件毕业设计
  5. Anaconda3的安装
  6. 特征匹配 + 单应性查找对象
  7. 机器学习也可以在线做!
  8. AE插件Stardust for mac(最强粒子特效)
  9. 如何在data visualization 中update svg_如何操作小程序页面中data数据区中的数据
  10. KICAD | 分享一个必须安装的插件Interactive HTML BOM plugin for KiCad