`
yangke_love
  • 浏览: 17321 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

DllMain介绍

阅读更多

转自:http://baike.baidu.com/view/3549543.htm

 

1 DLL的进入/退出函数

  1.1 DllMain简介

  跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain。以“DllMain”为关键字,来看看MSDN帮助文档怎么介绍这个函数的。

  The DllMain function is an optional method of entry into a dynamic-link library (DLL)。(简要翻译:对于动态链接库,DllMain是一个可选的入口函数。)这句话很重要,很多初学者可能都认为一个动态链接库肯定要有DllMain函数。其实不然,像很多仅仅包含资源信息的DLL是没有DllMain函数的。

 

  1.2 何时调用DllMain

  系统是在什么时候调用DllMain函数的呢?静态链接时,或动态链接时调用LoadLibrary和FreeLibrary都会调用DllMain函数。DllMain的第三个参数fdwReason指明了系统调用Dll的原因,它可能是:

  DLL_PROCESS_ATTACH、

  DLL_PROCESS_DETACH、

  DLL_THREAD_ATTACH

  DLL_THREAD_DETACH。

  以下从这四种情况来分析系统何时调用了DllMain。

 

  1.2.1 DLL_PROCESS_ATTACH

  大家都知道,一个程序要调用Dll里的函数,首先要先把DLL文件映射到进程的地址空间。要把一个DLL文件映射到进程的地址空间,有两种方法:静态链接和动态链接的LoadLibrary或者LoadLibraryEx。

  当一个DLL文件被映射到进程的地址空间时,系统调用该DLL的DllMain函数,传递的fdwReason参数为DLL_PROCESS_ATTACH。这种调用只会发生在第一次映射时。如果同一个进程后来为已经映射进来的DLL再次调用LoadLibrary或者LoadLibraryEx,操作系统只会增加DLL的使用次数,它不会再用DLL_PROCESS_ATTACH调用DLL的DllMain函数。不同进程用LoadLibrary同一个DLL时,每个进程的第一次映射都会用DLL_PROCESS_ATTACH调用DLL的DllMain函数。

  可参考DllMainTest的DLL_PROCESS_ATTACH_Test函数。

 

  1.2.2 DLL_PROCESS_DETACH

  当DLL被从进程的地址空间解除映射时,系统调用了它的DllMain,传递的fdwReason值是DLL_PROCESS_DETACH。当DLL处理该值时,它应该执行进程相关的清理工作。

  那么什么时候DLL被从进程的地址空间解除映射呢?两种情况:

  ◆FreeLibrary解除DLL映射(有几个LoadLibrary,就要有几个FreeLibrary)

 

  ◆进程结束而解除DLL映射,在进程结束前还没有解除DLL的映射,进程结束后会解除DLL映射。(如果进程的终结是因为调用了TerminateProcess,系统就不会用DLL_PROCESS_DETACH来调用DLL的DllMain函数。这就意味着DLL在进程结束前没有机会执行任何清理工作。)

 

  注意:当用DLL_PROCESS_ATTACH调用DLL的DllMain函数时,如果返回FALSE,说明没有初始化成功,系统仍会用DLL_PROCESS_DETACH调用DLL的DllMain函数。因此,必须确保清理那些没有成功初始化的东西。

  可参考DllMainTest的DLL_PROCESS_DETACH_Test函数。

 

  1.2.3 DLL_THREAD_ATTACH

  当进程创建一线程时,系统查看当前映射到进程地址空间中的所有DLL文件映像,并用值DLL_THREAD_ATTACH调用DLL的DllMain函数。

  新创建的线程负责执行这次的DLL的DllMain函数,只有当所有的DLL都处理完这一通知后,系统才允许进程开始执行它的线程函数。

  注意跟DLL_PROCESS_ATTACH的区别,我们在前面说过,第n(n>=2)次以后地把DLL映像文件映射到进程的地址空间时,是不再用DLL_PROCESS_ATTACH调用DllMain的。而DLL_THREAD_ATTACH不同,进程中的每次建立线程,都会用值DLL_THREAD_ATTACH调用DllMain函数,哪怕是线程中建立线程也一样。

 

  1.2.4 DLL_THREAD_DETACH

  如果线程调用了ExitThread来结束线程(线程函数返回时,系统也会自动调用ExitThread),系统查看当前映射到进程空间中的所有DLL文件映像,并用DLL_THREAD_DETACH来调用DllMain函数,通知所有的DLL去执行线程级的清理工作。

  注意:如果线程的结束是因为系统中的一个线程调用了TerminateThread,系统就不会用值DLL_THREAD_DETACH来调用所有DLL的DllMain函数。

 

 

  1.3 为DllMain换名

  在早期的SDK版本中,DllMain是叫做DllEntryPoint。其实有一件鲜为人知的事:一个Dll的入口函数名是可以自己定义的。下面我将以VC++6.0为例来演示如何更改。首先要说明一点,虽然DllMain可以换成其他函数名,但函数的参数和返回值必须和DllMain一样。而且这个函数要为__stdcall类型(DllMain本身也是__stdcall类型)。

 

  打开VC++菜单Project\Settings\Link tab\ Output in the Category box,如下图,在Entry-point symbol中输入要替换DllMain的函数名(当然这个函数名是你程序中已经实现的函数)。Entry-point symbol是干么的呢?可以以关键字“Entry-point symbol”搜索MSDN帮助文档查看,搜索时,打钩“仅搜索标题”会更快定位。

 

分享到:
评论
1 楼 coolhty 2013-05-15  
嘿,科长在学习VC啊

相关推荐

    dlllmian 介绍和编译连接错误

    本文将重点介绍DLL中的一个关键函数——`DllMain`,以及与其相关的编译连接错误。 #### 一、DLL简介 DLL是一种特殊类型的库文件,它包含可以被多个程序同时使用的代码和数据。通过使用DLL,可以减少内存占用,简化...

    vs2010创建和使用动态链接库(dll)~教程和VS工程实例.rar

    下面将详细介绍这个过程。 一、创建DLL项目 1. 打开Visual Studio 2010,选择“文件”>“新建”>“项目”,在弹出的对话框中,选择“Win32控制台应用程序”。 2. 在“应用程序设置”对话框中,确保“动态链接库...

    VC 中的DLL介绍

    非MFC DLL 7 4.1一个简单的DLL 7 4.2 声明导出函数 11 4.3 DLL的调用方式 12 4.4 DllMain函数 14 4.5 __stdcall约定 18 4.6 DLL导出变量 19 4.7 DLL导出类 23 5. MFC规则DLL 32...

    用devc++制作动态链接库

    本文将详细介绍如何使用Dev-C++这一集成开发环境(IDE)来创建和调用动态链接库。 #### 开发环境配置与创建项目 Dev-C++是一个基于MinGW的免费开源IDE,特别适合于学习C/C++编程。尽管Dev-C++并非最现代化的IDE,...

    C++小知识:用合适的工具来分析你的代码

    本篇文章通过一个具体的例子,介绍了如何利用静态分析工具解决一个困扰开发者的谜题。这个例子涉及到了在`DllMain`函数中错误地使用`CreateThread`API的问题。`DllMain`函数是动态链接库(DLL)的入口点,它在DLL被...

    图文手把手教你一步步用VC 2010编写通达信缠论插件(1-DLL设计入门).pdf

    3. DLL入口点(DllMain)的编写:文档展示了如何编写DLL的入口点函数DllMain,这是DLL初始化和终止过程中必须的。在VC++中,DllMain是一个被系统调用的函数,用于处理DLL加载、卸载以及线程和进程的附加和分离事件。...

    实用工具软件环境(第4章)-VISUALBASIC讲义.ppt

    本章详细介绍了DLL的基本概念、类型、生成与使用,以及在Visual C++中的应用。动态连接库在Windows程序设计中扮演着重要角色,它允许代码和资源在多个程序间共享,从而提高效率,节省内存和硬盘空间。 4.1 动态连接...

    SharpNeedle:将C#代码注入正在运行的进程

    大多数dll注入教程将在上半部分详细介绍,但随后您将不得不从DllMain中运行代码,这是一个危险且有限的命题。 有关为什么应避免在DllMain中执行任何有趣操作的更多信息,请阅读Raymond Chen的。 该项目旨在改变...

    已有objectarx项目支持OPM步骤

    本文档主要介绍如何在已经创建的ObjectARX项目中添加对OPM的支持,具体步骤如下: 1. 创建新的OPM支持项目: 首先,你需要在Visual Studio 2005中创建一个新的ObjectARX项目,确保在项目向导中选择支持OPM的选项。...

    学习dll编程的小例子

    本教程将通过一个简单的C++示例,介绍如何创建和使用DLL文件。 首先,我们需要理解DLL的工作原理。在Windows环境下,当你运行一个程序时,并不一定会加载所有依赖的库文件到内存中。相反,只有在需要时,才会动态地...

    C语言创建DLL,并在C中调用DLL

    在这篇文章中,我们将详细介绍如何创建DLL文件,以及如何在C语言中调用DLL文件。 一、DLL的概念和作用 DLL(Dynamic Link Library)是Windows操作系统中的一种库文件,用于存储可执行代码和数据。DLL文件可以被多...

    按键C++版的滚轮

    在本文中,我们将详细介绍如何使用C++语言来实现按键C++版的滚轮消息按键。 首先,我们需要在DLL中定义一个钩子函数,用于捕捉鼠标事件。在本例中,我们使用了`SetWindowsHookEx`函数来设置鼠标钩子,并将其关联到...

    C++学习之路

    ### C++ DLL 学习知识...通过以上介绍,我们可以看到 DLL 在 C++ 开发中扮演着重要的角色。不仅能够提高代码的复用率,还可以简化程序的部署与维护过程。掌握 DLL 的创建和使用方法对于提升软件开发效率具有重要意义。

    CVI生成动态连接库(DLL)步骤简介.txt

    本篇将详细介绍如何在CVI中生成动态链接库(DLL),并解析关键代码片段。 #### 二、DLL基础概念 动态链接库(DLL)是一种可被多个应用程序共享的代码模块。在Windows操作系统中,DLL是标准的共享库实现方式之一。...

    dll编程深入浅出含代码-个人整合

    8. **dll编程深入浅出之4.4 DllMain函数代码.zip**:DllMain是每个DLL的入口点,这个部分可能讲解了DllMain函数的作用,以及如何在DLL初始化和卸载时执行特定操作。 通过这些代码示例和详细解释,学习者可以从实践...

    神奇的马甲DLL(dll挟持技术介绍)

    例如,在DLL的入口点dllmain中加载系统目录下的lpk.dll,实现函数转发的同时,还可以添加钩子函数hookDeviceIoControl以实现特定功能。 #### 六、总结与展望 DLL挟持技术,尽管源自较早的Windows版本,但在现代...

    基于Visual C++6.0的DLL编程实现

    本文将详细介绍基于Visual C++ 6.0环境下DLL编程的实现过程,以帮助读者更好地理解和掌握DLL的创建和使用。 首先,我们需要明确DLL的概念。DLL是Dynamic Link Library(动态链接库)的缩写,它是一种特殊的库文件,...

    VS下C++生成库并完成调用测试程序

    本篇将详细介绍如何在VS2015中创建C++动态链接库(DLL)以及如何编写和运行测试程序。 一、创建动态链接库(DLL) 1. 启动VS2015,创建一个新的项目。选择“文件” > “新建” > “项目”,在项目模板中找到...

    dll编写教程

    本教程将详细介绍DLL的编写过程,包括其优点、基本结构以及如何创建一个简单的DLL。 首先,DLL的主要优点如下: 1) 节省内存:DLL中的代码和数据在内存中只加载一次,所有使用该DLL的进程都可以共享,避免了重复...

Global site tag (gtag.js) - Google Analytics