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帮助文档查看,搜索时,打钩“仅搜索标题”会更快定位。
分享到:
相关推荐
本文将重点介绍DLL中的一个关键函数——`DllMain`,以及与其相关的编译连接错误。 #### 一、DLL简介 DLL是一种特殊类型的库文件,它包含可以被多个程序同时使用的代码和数据。通过使用DLL,可以减少内存占用,简化...
下面将详细介绍这个过程。 一、创建DLL项目 1. 打开Visual Studio 2010,选择“文件”>“新建”>“项目”,在弹出的对话框中,选择“Win32控制台应用程序”。 2. 在“应用程序设置”对话框中,确保“动态链接库...
非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...
本文将详细介绍如何使用Dev-C++这一集成开发环境(IDE)来创建和调用动态链接库。 #### 开发环境配置与创建项目 Dev-C++是一个基于MinGW的免费开源IDE,特别适合于学习C/C++编程。尽管Dev-C++并非最现代化的IDE,...
本篇文章通过一个具体的例子,介绍了如何利用静态分析工具解决一个困扰开发者的谜题。这个例子涉及到了在`DllMain`函数中错误地使用`CreateThread`API的问题。`DllMain`函数是动态链接库(DLL)的入口点,它在DLL被...
3. DLL入口点(DllMain)的编写:文档展示了如何编写DLL的入口点函数DllMain,这是DLL初始化和终止过程中必须的。在VC++中,DllMain是一个被系统调用的函数,用于处理DLL加载、卸载以及线程和进程的附加和分离事件。...
本章详细介绍了DLL的基本概念、类型、生成与使用,以及在Visual C++中的应用。动态连接库在Windows程序设计中扮演着重要角色,它允许代码和资源在多个程序间共享,从而提高效率,节省内存和硬盘空间。 4.1 动态连接...
大多数dll注入教程将在上半部分详细介绍,但随后您将不得不从DllMain中运行代码,这是一个危险且有限的命题。 有关为什么应避免在DllMain中执行任何有趣操作的更多信息,请阅读Raymond Chen的。 该项目旨在改变...
本文档主要介绍如何在已经创建的ObjectARX项目中添加对OPM的支持,具体步骤如下: 1. 创建新的OPM支持项目: 首先,你需要在Visual Studio 2005中创建一个新的ObjectARX项目,确保在项目向导中选择支持OPM的选项。...
本教程将通过一个简单的C++示例,介绍如何创建和使用DLL文件。 首先,我们需要理解DLL的工作原理。在Windows环境下,当你运行一个程序时,并不一定会加载所有依赖的库文件到内存中。相反,只有在需要时,才会动态地...
在这篇文章中,我们将详细介绍如何创建DLL文件,以及如何在C语言中调用DLL文件。 一、DLL的概念和作用 DLL(Dynamic Link Library)是Windows操作系统中的一种库文件,用于存储可执行代码和数据。DLL文件可以被多...
在本文中,我们将详细介绍如何使用C++语言来实现按键C++版的滚轮消息按键。 首先,我们需要在DLL中定义一个钩子函数,用于捕捉鼠标事件。在本例中,我们使用了`SetWindowsHookEx`函数来设置鼠标钩子,并将其关联到...
### C++ DLL 学习知识...通过以上介绍,我们可以看到 DLL 在 C++ 开发中扮演着重要的角色。不仅能够提高代码的复用率,还可以简化程序的部署与维护过程。掌握 DLL 的创建和使用方法对于提升软件开发效率具有重要意义。
本篇将详细介绍如何在CVI中生成动态链接库(DLL),并解析关键代码片段。 #### 二、DLL基础概念 动态链接库(DLL)是一种可被多个应用程序共享的代码模块。在Windows操作系统中,DLL是标准的共享库实现方式之一。...
8. **dll编程深入浅出之4.4 DllMain函数代码.zip**:DllMain是每个DLL的入口点,这个部分可能讲解了DllMain函数的作用,以及如何在DLL初始化和卸载时执行特定操作。 通过这些代码示例和详细解释,学习者可以从实践...
例如,在DLL的入口点dllmain中加载系统目录下的lpk.dll,实现函数转发的同时,还可以添加钩子函数hookDeviceIoControl以实现特定功能。 #### 六、总结与展望 DLL挟持技术,尽管源自较早的Windows版本,但在现代...
本文将详细介绍基于Visual C++ 6.0环境下DLL编程的实现过程,以帮助读者更好地理解和掌握DLL的创建和使用。 首先,我们需要明确DLL的概念。DLL是Dynamic Link Library(动态链接库)的缩写,它是一种特殊的库文件,...
本篇将详细介绍如何在VS2015中创建C++动态链接库(DLL)以及如何编写和运行测试程序。 一、创建动态链接库(DLL) 1. 启动VS2015,创建一个新的项目。选择“文件” > “新建” > “项目”,在项目模板中找到...
本教程将详细介绍DLL的编写过程,包括其优点、基本结构以及如何创建一个简单的DLL。 首先,DLL的主要优点如下: 1) 节省内存:DLL中的代码和数据在内存中只加载一次,所有使用该DLL的进程都可以共享,避免了重复...