精华内容
下载资源
问答
  • dllmain

    2021-03-19 22:59:33
    win32提供了一个特殊函数名叫DllMain,这个函数写在dll中会根据四种情况进行回调。 某个线程加载了dll 某个线程卸载了dll 主进程加载了dll 主进程卸载了dll 微软dllmain官方文档 我们在dll工程随意新建一个类 //My...

    win32提供了一个特殊函数名叫DllMain,这个函数写在dll中会根据四种情况进行回调。

    1. 某个线程加载了dll
    2. 某个线程卸载了dll
    3. 主进程加载了dll
    4. 主进程卸载了dll

    微软dllmain官方文档

    我们在dll工程随意新建一个类

    //My.cpp
    #include<iostream>
    #include<process.h>
    
    #include <windows.h>
    using namespace std;
    BOOL WINAPI DllMain(
    	_In_ HINSTANCE hinstDLL,
    	_In_ DWORD     fdwReason,//调用的原因,
    	_In_ LPVOID    lpvReserved //保留使用
    ) {
    	switch (fdwReason)
    	{
    	//主进程加载了dll
    	case DLL_PROCESS_ATTACH:
    		cout <<"DLL_PROCESS_ATTACH" <<endl;
    		break;
    	//主进程卸载了dll
    	case DLL_PROCESS_DETACH:
    		cout << "DLL_PROCESS_DETACH" << endl;
    
    		break;
    	}
    	//如果动态加载的dll的话,返回false 那么LoadLibrary返回null
    	//如果静态加载的dll的话  返回false 进程直接奔溃
    	return TRUE;
    }
    

    我们看下使用库的地方

    // UseLib.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include <iostream>
    
    #include <windows.h>
    
    using namespace std;
    
    typedef int(*myAdd)(int a, int b);
    int main()
    {
    	//加载我们的动态库 请放入exe运行路径或者放入系统`C:\Windows\SysWOW64\`
    	HMODULE loadLibrary = LoadLibrary("MyDll.dll");
    	//通过name
    	myAdd procAddress = (myAdd)GetProcAddress(loadLibrary, (LPCSTR)1);
    	//通过ordinal
    	//myAdd procAddress2 = (myAdd)GetProcAddress(loadLibrary, (LPCSTR)12);
    
    	int result = procAddress(1, 2);
    	//int result2 = procAddress2(1, 2);
    	cout << result  << endl;
    	//从程序中卸载dll
    	FreeLibrary(loadLibrary);
    	
    }
    
    

    输出:

    DLL_PROCESS_ATTACH
    3
    DLL_PROCESS_DETACH
    
    展开全文
  • DllMain

    2020-09-07 11:15:49
    跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain。以“DllMain”为关键字,来看看MSDN帮助文档怎么介绍这个函数的。 简介编辑 The DllMain function is an optional method of entry into ...

    跟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
    3
    4
    5
    6
    BOOL WINAPI DllMain(
    In HINSTANCE hinstDLL, // 指向自身的句柄
    In DWORD fdwReason, // 调用原因
    In LPVOID lpvReserved // 隐式加载和显式加载
    );
    // 以上内容来自MSDN
    何时调用编辑
    系统是在什么时候调用DllMain函数的呢?静态链接时,或动态链接时调用LoadLibrary和FreeLibrary都会调用DllMain函数。DllMain的第二个参数fdwReason指明了系统调用Dll的原因,它可能是::
    DLL_PROCESS_ATTACH、
    DLL_PROCESS_DETACH、
    DLL_THREAD_ATTACH、
    DLL_THREAD_DETACH。
    以下从这四种情况来分析系统何时调用了DllMain。
    进程映射
    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函数。
    进程卸载
    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函数。
    线程映射
    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函数,哪怕是线程中建立线程也一样。
    线程卸载
    DLL_THREAD_DETACH
    如果线程调用了ExitThread来结束线程(线程函数返回时,系统也会自动调用ExitThread),系统查看当前映射到进程空间中的所有DLL文件映像,并用DLL_THREAD_DETACH来调用DllMain函数,通知所有的DLL去执行线程级的清理工作。
    注意:如果线程的结束是因为系统中的一个线程调用了TerminateThread,系统就不会用值DLL_THREAD_DETACH来调用所有DLL的DllMain函数。

    展开全文
  • DLLMain

    2014-03-19 23:25:00
    1DLL的进入/退出函数1.1 DllMain简介跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain。以“DllMain”为关键字,来看看MSDN帮助文档怎么介绍这个函数的。TheDllMainfunctio...
    转自Kroosafehttp://blog.csdn.net/kroosafe/article/details/3454840
    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 byhLibModule. This can reduce the size of the working code set for some applications.
     

    转载于:https://www.cnblogs.com/woniuzhongdetou/p/3612618.html

    展开全文
  • dllMain

    千次阅读 2012-03-14 20:14:03
    // dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call,
     
    // dllmain.cpp : Defines the entry point for the DLL application.
    #include "stdafx.h"
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
          )
    {
     switch (ul_reason_for_call)
     {
     case DLL_PROCESS_ATTACH:
     case DLL_THREAD_ATTACH:
     case DLL_THREAD_DETACH:
     case DLL_PROCESS_DETACH:
      break;
     }
     return TRUE;
    }
    
    


    由第一句的注释可知,DLLMain函数。

    #define APIENTRY    WINAPI,即以WINAPI方式调用。

     

    进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识,只有在特定的进程内部有效,句柄代表了DLL模块在进程虚拟空间中的起始地址。在Win32中,HINSTANCE和HMODULE的值是相同的,这两种类型可以替换使用,这就是函数参数hModule的来历。

     


    在DLLMain函数中做如下修改:

    switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    		printf("DLL_PROCESS_ATTACH\n");
    		break;
    	case DLL_THREAD_ATTACH:
    		printf("DLL_THREAD_ATTACH\n");
    		break;
    	case DLL_THREAD_DETACH:
    		printf("DLL_THREAD_DETACH\n");
    		break;
    	case DLL_PROCESS_DETACH:
    		printf("DLL_PROCESS_DETACH\n");
    		break;
    	}
    	return TRUE;

     在cpp文件中修改函数地址函数为:(lpAddFun)GetProcAddress(hDLL, MAKEINTRESOURCE(1) );

    其中MAKEINTRESOURCE它直接通过.def文件中为add函数指定的顺序号访问add函数,具体体现在MAKEINTRESOURCE ( 1 ),MAKEINTRESOURCE是一个通过序号获取函数名的宏,定义为(节选自winuser.h):

    #define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i)))

    #define MAKEINTRESOURCEW(i) (LPWSTR)((DWORD)((WORD)(i)))

    #ifdef UNICODE

    #define MAKEINTRESOURCE MAKEINTRESOURCEW

    #else

    #define MAKEINTRESOURCE MAKEINTRESOURCEA


    输出为:DLL_PROCESS_ATTACH 。。。 DLL_PROCESS_ATTACH

     

    展开全文
  • 拯救dllmain冲突

    2018-08-22 10:45:08
    在做MFC的动态库时,经常会遇DllMain重定义的问题,此问题让很多开发人员十分烦恼,其实主要是自己添加的DllMain和MFC内部封装的入口函数冲突,希望此文件能帮您解决问题。
  • DllMain 用法

    2018-07-02 20:19:00
    1.1 DllMain简介 跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain。以“DllMain”为关键字,来看看MSDN帮助文档怎么介绍这个函数的。 The DllMain function is an optional method of ...
  • DllMain详解

    2018-04-20 14:49:04
    本文转载自:https://blog.csdn.net/benkaoya/article/details/25047811 DLL的进入/退出函数1.1 DllMain简介跟exe...以“DllMain”为关键字,来看看MSDN帮助文档怎么介绍这个函数的。The DllMain function is an o...
  • Unsafe DllMain usage

    2021-01-06 11:31:22
    <p>In short, it appears that an invocation of DllMain can call back into user callbacks on graph nodes, which is unsafe because while a DllMain is open a loader lock is established in windows....
  • DllMain简介

    2014-12-09 20:29:29
    1.1 DllMain简介 跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain。以“DllMain”为关键字,来看看MSDN帮助文档怎么介绍这个函数的。 The DllMain function is an optional method...
  • Dllmain的作用

    2019-10-08 22:17:35
    DllMain函数是DLL模块的默认入口点。当Windows加载DLL模块时调用这一函数。系统首先调用全局对象的构造函数,然后调用全局函数 DLLMainDLLMain函数不仅在将DLL链接加载到进程时被调用,在DLL模块与进程分离时...
  • dllmain简介

    2015-01-08 22:12:57
    The DllMain function is an optional method of entry into a dynamic-link library (DLL)。(简要翻译:对于动态链接库,DllMain是一个可选的入口函数。)这句话很重要,很多初学者可能都认为一个动态链接库肯定要...
  • DLLMain函数

    千次阅读 2015-10-05 23:30:29
    DLLMain函数原型:BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to DLL module DWORD fdwReason, // reason for calling function LPVOID lpvReserved // reserved ); 跟exe有个main或者WinMain入口函数...
  • dllMain函数

    2014-11-27 10:35:00
    一些例子中,DLL并没有提供DllMain函数,应用工程也能成功引用DLL,这是因为Windows在找不到DllMain的时候,系统会从其它运行库中引入一个不做任何操作的缺省DllMain函数版本,并不意味着DLL可以放弃DllMain函数。...
  • DllMain 详解

    2014-04-15 21:46:31
    ... DLL的进入/退出函数1 DllMain简介跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain。以“DllMain”为关键字,来看看MSDN帮助文档怎么介绍这个函数的。The DllMain

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,769
精华内容 707
关键字:

dllmain