DllMain详解

windows:加载dll时的DLLMain介绍 在实际开发中,通常情况下,系统自带的初始化和清理机制(如全局变量初始化和析构、自动内存管理等)已经足够。然而,有些特定场景下,需要开发者自己在DllMain中处理和。以下是一些可能的情况:线程本地存储(TLS)当需要在每个线程中维护独立的数据(如线程本地存储),必须手动进行线程初始化和清理。例如,多线程日志记录、线程特定的配置等。示例:每个线程都有独立的日志文件句柄或配置对象。资源管理当需要在DLL加载时分配全局资源(如文件句柄、网络连接)并在卸载时释放这些资源时,必须手动进行初始化和清理。示例。 阅读详情
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)。(简要翻译:对于一个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的映射的情况。(如果进程的终结是因为调用了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帮助文档查看,搜索时,打钩“仅搜索标题”会更快定位。 
 
         按OK后,如果马上编译的话会出现如下错误: 
LIBCMTD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main 
Debug/Dll.dll : fatal error LNK1120: 1 unresolved externals 
打开VC++菜单Project\Settings\C/C++选项卡,如下图,在Project Options:末尾的地方添加”/D”(图中蓝色高亮的地方),要注意位置,我试了,要把/D放到/GZ后面也会链接错误,我也不懂为什么,^_^。按OK,再次编译,成功。大家可以自己测试下到底有没有更改成功,什么,如果测试?打出调式信息啊。 
 
1.4 DisableThreadLibraryCalls 
看帮助就知道它是干么用的: 
The DisableThreadLibraryCalls function disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications for the dynamic-link library (DLL) specified by hLibModule. This can reduce the size of the working code set for some applications.
C++-dllmain介绍 dllmain 百度解释的很清楚 跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain,对于动态链接库,DllMain是一个可选的入口函数 入口函数定义 BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, // 指向自身的句柄 _In_ DWORD fdwReason, // 调用原因 _In_ LPVOID lpvReserved // 隐式加载和显式加载 ); 系统在调用LoadLibrary和Fre 阅读详情

相关推荐

C++动态链接库入口dllmain详解

通过使用dllmain函数,我们可以在DLL被加载和卸载时执行相应的初始化和释放资源操作。而在C++中,DLL的入口函数被称为dllmain。需要注意的是,dllmain函数是一个非常敏感的函数,它应该保持简洁并且不应该执行耗时的操作。在dllmain函数中,不建议创建新线程或进行复杂的初始化过程,因为这可能会导致不可预料的问题。除了在dllmain函数中执行初始化和释放资源的操作,我们还可以在DLL中定义其他函数供外部调用。dllmain函数是DLL中的特殊函数,它在DLL被加载和卸载时被调用。

2301_79331230的博客 1180

DLL文件_DLLMain函数详解

目录**CODE**1.DLLMain函数类型-APIENTRY CODE //核心的入口函数,动态链接库入口函数 BOOL APIENTRY DllMain( HMODULE hModule, //APIENTRY可以换成WINAPI或者_stdcall 是一种调用约定 DWORD ul_reason_for_call, LPVOID lpReserved )

weixin_46967682的博客 7367

C++ 之动态链接库DLL使用注意事项及C#调用详解

C++ 之动态链接库DLL使用注意事项及C#调用详解

yohnyang的博客 2382

关于Dll

Dll(动态链接库)的加载分为2种: 静态加载 动态加载 首先来看一个Dll的例子: 上面3张图分别是main.cpp, Test.h以及Test.cpp。其编译连接后生成了一个名为Sample.dll以及对应的Sample.lib导入库。 静态加载是通过如下几种方式使用: 首先可以通过#pragma comment语句来静态使用dll 或者可以通过在项目属性中的附加依赖项添加对应的导入库来静态使用 这种情况下就无需#pragma comment语句了 ...

輚至消亡 2642

液晶屏LVDS接口:【图文详讲】

​LVDS(Low Voltage Differential Signaling,即低电压差分信号)接口又称RS-644总线接口,是20世纪90年代才提出的一种数据传输和接口技术。LVDS接口是美国NS美国国家半导体公司为克服以TTL电平方式传输宽带高码率数据时功耗大,电磁干扰大等缺点而研制的一种数字视频信号传输方式

weixin_66299220的博客 1万+

uniapp map地图实现marker聚合点,并点击marker触发事件

【代码】uniapp map地图实现marker聚合点,并点击marker触发事件。

weixin_44705979的博客 5437

4-DllMain详解

当线程C执行DIlMain函数中的代码时,线程B创建线程D,此时系统必须再次用DLL_THREAD_ATTACH来调用SomeDLL.dll的DllMain函数,但这次是让线程D来执行其中的代码。DllMain函数执行的时候,Windows会为它创建一个加载器锁,加载器锁可以被任意需要访问加载到进程中的DLL列表的函数获取到,这其中包括GetModuleHandle和GetModuleFileName之类的函数。DLL的入口函数一般被用作根据不同的通知信号,来执行相关的进程或线程的初始化和清理工作,

weixin_40332490的博客 1230

C++新手也能搞定!Windows下Cesium-Native编译全流程(附依赖下载技巧)

本文为C++新手详细介绍了在Windows系统下编译Cesium-Native库的全流程。重点针对网络环境不佳的情况,提供了手动下载依赖库的实用技巧,并指导用户使用CMake配置、生成解决方案,最终完成编译与测试验证,帮助开发者成功构建这一处理3D地理空间数据的C++运行时库。

weixin_28839549的博客 380

对DllMain的误解

     一直以来对DllMain的了解也就局限于,实验性的在DllMain里面写上: cout        我在DllMain里面这样写的代码:BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){

tangaowen的专栏 4368

深入解析Sigma Delta调制器 —— 从电流采样到数字信号处理的完整链路

本文深入解析了Sigma Delta调制器的工作原理与应用。通过剖析过采样、噪声整形与负反馈核心机制,并结合AMC1306等实例,详细阐述了从电流采样到数字信号处理的完整链路。该技术凭借其高精度和高抗干扰能力,在ADC、电流测量及音频处理等领域发挥着关键作用。

ttt77的博客 643

K210学习笔记(八)——人脸检测和人脸识别

前言 人脸检测是人脸识别算法的第一步,人脸识别过程主要分为人脸图像获取、人脸检测、人脸配准、人脸表征以及人脸图像匹配与识别。人脸检测的目标是找出图像中所有的人脸对应的位置,算法的输出是人脸外接矩形(椭圆)在图像中的坐标,可能还包括姿态如倾斜角度等信息。人脸检测在安防监控,人证比对,人机交互,社交和娱乐等方面有很强的应用价值。 人脸识别是在人脸检测的基础上除了检测到人脸的位置以外, 还可以识别到这个人是谁,利用分析比较是基于人的脸视觉部特征信息进行身份鉴识别的计算机一种生物识别技术。 一、KPU模块方法 1、

Thousand_drive的博客 1万+

Windows动态库DllMain

DllMain DllMain是Windows动态库的入口函数。如同控制台或DOS程序需要main函数、WIN32程序需要WinMain函数一样,Windows在加载DLL的时候,需要一个入口函数。 注意事项 实际编写动态库时,DLL并没有提供DllMain函数,应用工程也能成功引用DLL,这是因为Windows在找不到DllMain的时候,系统会从其它运行库中引入一个不做任何操作的缺省DllMain函数版本,并不意味着DLL可以放弃DllMain函数。 根据编写规范,Windows必须

beibeix2015的博客 1005

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的零售柜商品检测软件(Python+PySide6界面+训练代码)

随着新零售概念的兴起,无人零售柜、智能零售店等新型零售模式快速发展。传统零售柜依赖于人工盘点和补货,效率低下且成本高昂。本文提出了一种基于YOLO系列目标检测算法的零售柜商品检测系统,实现了对零售柜内商品的自动识别、计数和库存管理。系统采用PySide6开发用户界面,集成了YOLOv5、YOLOv6、YOLOv7和YOLOv8等多种先进的深度学习模型,提供了完整的训练和推理流程。本文将详细介绍系统设计、算法实现、数据集构建和实际应用效果,并提供完整的代码实现。

YOLO 333

DLL专题之DllMain函数

DllMain函数,并没有什么好讲的.不就是加载和卸载DLL的时候用嘛!实际上,也不是这样.在一些高级应用中是很有用处的.今天,我们只是简单的测试测试.没有什么技术含量的.呵呵.那我们就看看吧:首先,老步骤,建立一个Win32 DynamicLink(dll)选择一个简单的工程.,代码如下:头文件:#ifndef _DLLMAIN_DLL_H_#define _DLLMAIN_DLL_

章志强 8574

46.qt quick-自定义非常好看的qml虚拟软键盘-支持换肤、动态加载移除语言(二)

在上章我们学习了45.qt quick-qml虚拟软键盘详解(一)_诺谦的博客-优快云博客 接下来我们便来自定义一款好看的qml软键盘.如下图所示: 支持背景更换、支持动图: 支持动态加载移除语言: 支持拖拽、自由缩小放大: 支持定位坐标: ...

抵抗时间扭曲,坚持做一件有意义的事 4674

基于YOLOv11的农作物病虫害检测系统设计与实现

我们使用公开的IP102病虫害数据集作为基础,该数据集包含102种病虫害类别,覆盖水稻、小麦、玉米等多种主要农作物。图像数量:75,222张类别数:102图像分辨率:从640×480到4000×3000不等标注格式:PASCAL VOC格式此外,我们还收集了部分田间实际拍摄的图像以增强模型泛化能力。

YOLO 595

关于dllMain死锁的问题

前几天遇到了一个死锁问题,查了很久没查出来,最后发现是在dllMain中结束线程导致死锁。 起因:是修改了某个模块,在init函数里启动线程,在uninit函数里结束线程,开始并不知道init和uninit是从dllMain调过来的,也不知道dllmain中结束线程会导致死锁。 具体原因:每次进入dllMain时都会持有一个loader-lock,而结束线程也会进入dllMain,结果就死锁了

mxc的专栏 635

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

DllMain中不当操作导致死锁问题的分析--进程对DllMain函数的调用规律的研究和分析

不知道大家是否思考过一个过程:系统试图运行我们写的程序,它是怎么知道程序起始位置的?很多同学想到,我们在编写程序时有个函数,类似Main这样的名字。是的!这就是系统给我们提供的控制程序最开始的地方(注意这儿是提供给我们的,而实际有比这个还要靠前的main)。于是看到DllMain就可以想到它是干嘛的了:Dll的入口点函数。那何时调用这个函数的呢?以及各种调用场景都传给了它什么参数呢...

方亮的专栏 6672

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

DllMain

转自:https://docs.microsoft.com/zh-cn/windows/win32/dlls/dllmain

yjianlu的专栏 189

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

在DLL 的DllMain函数中创建线程

最近在写一个代码的时候想在DLL的DllMain

bobopeng 6866
上一篇: 学C++和VC如何入门,如何提高?
下一篇: CAtlModule类的实现
GWeruo
博客等级 码龄18年 13粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值