精华内容
下载资源
问答
  • DllMain使用的注意事项

    2019-09-12 19:28:23
    https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx 转载于:https://my...

    https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx

    转载于:https://my.oschina.net/Yuqingmu/blog/466576

    展开全文
  • 动态链接库的显示链接使用示例: /* *test.c */ #include <windows.h> //1.定义函数指针 typedef int(*lpAdd)(int, int); //2.声明函数指针变量 lpAdd add; int WINAPI WinMain(HINSTANCE ...

    上一篇我们用的是动态链接库的隐式链接,加载调用不需手动去设置;
    动态链接库的显示链接使用示例:

    /*
     *test.c
     */
    #include <windows.h>
    
    //1.定义函数指针
    typedef int(*lpAdd)(int, int);
    //2.声明函数指针变量
    
    lpAdd add;
    
    int WINAPI WinMain(HINSTANCE hInstance,	
    	HINSTANCE hPrevInstance,
    	PSTR szCmdLine,
    	int iCmdShow)
    {
    	//3.加载动态库
    	HINSTANCE hModule = LoadLibrary(TEXT("add.dll"));
    	//4.获取函数地址
    	add = (lpAdd)GetProcAddress(hModule, "add");
    	//5.调用函数
    	int x = add(3, 5);
    	//6.释放动态链接库
    	FreeLibrary(hModule);
    
    	return 0;
    }
    

    DLLMain使用示例:

    /*
     *DllMain.c
     *此文件用来生成DllMain.dll,生成完后放入test.c源代码目录下
     */
    #include <windows.h>
    
    BOOL WINAPI DllMain(
    	_In_ HINSTANCE hinstDLL,
    	_In_ DWORD     fdwReason,
    	_In_ LPVOID    lpvReserved
    	)
    {
    	switch (fdwReason){
    		//1.DLL_PROCESS_ATTACH(LoadLibrary())
    	    case  DLL_PROCESS_ATTACH:
    			MessageBox(NULL, TEXT("1.DLL_PROCESS_ATTACH"), TEXT("LoadLibrary"), MB_OK);
    			break;
    		//2.DLL_PROCESS_DETACH(FreeLibrary())
    		case  DLL_PROCESS_DETACH:
    			MessageBox(NULL, TEXT("2.DLL_PROCESS_DETACH"), TEXT("FreeLibrary"), MB_OK);
    			break;
    		//3.DLL_THREAD_ATTACH(Thread LoadLibrary())
    		case  DLL_THREAD_ATTACH:
    			MessageBox(NULL, TEXT("3.DLL_THREAD_ATTACH "), TEXT("线程中使用LoadLibrary"), MB_OK);
    			break;
    		//4.DLL_THREAD_DETACH
    		case  DLL_THREAD_DETACH:
    			MessageBox(NULL, TEXT("4.DLL_THREAD_DETACH  "), TEXT("线程结束"), MB_OK);
    			break;
    	}
    	return TRUE;
    }
    
    
    
    /*
     *test.c
     */
    #include <stdio.h>
    #include <windows.h>
    
    DWORD WINAPI ThreadProc(LPVOID lpThreadParameter)
    {
    	HINSTANCE hModule = LoadLibrary(TEXT("DllMain.dll"));
    
    	return 0;
    }
    int WINAPI WinMain(HINSTANCE hInstance,	
    	HINSTANCE hPrevInstance,
    	PSTR szCmdLine,
    	int iCmdShow)
    {
    	//加载动态库
    	HINSTANCE hModule = LoadLibrary(TEXT("DllMain.dll"));
    	
    	CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
    
    	//睡一下让创建的线程跑起来
    	Sleep(1000);
    	//释放动态链接库
    	FreeLibrary(hModule);
    
    	return 0;
    }
    

    由此可见,DllMain有四种情况下会被调用;

    展开全文
  • 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...
  • 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使用GetModuleFileName

    千次阅读 2007-12-08 13:32:00
    DllMain使用GetModuleFileName即可.代码大致如下:#define STR_SZ 256BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved){ TCHAR str[STR_SZ]={0}; switch( fdwReason ) { cas
  • 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...
  • 这里说的DllMain是指Win32 dll的入口函数,在这个函数中不能使用任何的托管代码,也就是说MSIL代码。 再进一步,DllMain存在的dllmain.cpp也是个特殊文件: 1)这个文件不能使用预编译头。只要你设置了需要使用预...
  • dllmain简介

    2015-01-08 22:12:57
    The DllMain function is an optional method of entry into a dynamic-link library (DLL)。(简要翻译:对于动态链接库,DllMain是一个可选的入口函数。)这句话很重要,很多初学者可能都认为一个动态链接库肯定要...
  • DllMain使用GetModuleFileName即可.代码大致如下:#define STR_SZ 256BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved){ TCHAR str[STR_SZ]={0}; switch( fdwReason ) { case
  • DllMain 用法

    千次阅读 2014-01-11 11:26:28
    1.1 DllMain简介  跟exe有个main或者WinMain入口函数一样,DLL也有一个入口函数,就是DllMain。以“DllMain”为关键字,来看看MSDN帮助文档怎么介绍这个函数的。  The DllMain function is an optional method ...
  • 拯救dllmain冲突

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

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

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,770
精华内容 6,308
关键字:

dllmain使用