概述
DllMain的执行线程
DllMain()有4个通知:
DLL_PROCESS_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_DETACH
DLL_PROCESS_DETACH
其中:DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH由主线程执行
DLL_THREAD_ATTACH由新建线程执行,DLL_PROCESS_DETACH由消亡线程执行
对于隐式加载的DLL来说,应用程序会在执行main函数前加载DLL,执行main函数后卸载DLL。其过程如下:
1)应用程序主线程执行DllMain(),通知DLL_PROCESS_ATTACH
2)应用程序主线程执行main()
3)程序中新建线程,为已加载的DLL执行DllMain(),通知DLL_THREAD_ATTACH
4)线程执行线程函数
5)线程退出线程函数
6)线程为已加载的DLL执行DllMain(),通知DLL_THREAD_DETACH
7)应用程序主线程退出main()
8)应用程序主线程执行DllMain(),通知DLL_PROCESS_DETACH
测试代码:
一个DLL工程,导出一个函数void Foo();
//
dllmain.cpp : 定义DLL 应用程序的入口点。
#include " stdafx.h "
#include <tchar.h>
#include <stdio.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
const int kBuffLen = 256;
TCHAR szLog[kBuffLen];
DWORD dwThreadId = ::GetCurrentThreadId();
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
_stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_PROCESS_ATTACHn "), dwThreadId);
OutputDebugString(szLog);
}
break;
case DLL_THREAD_ATTACH:
{
_stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_THREAD_ATTACHn "), dwThreadId);
OutputDebugString(szLog);
}
break;
case DLL_THREAD_DETACH:
{
_stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_THREAD_DETACHn "), dwThreadId);
OutputDebugString(szLog);
}
break;
case DLL_PROCESS_DETACH:
{
_stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_PROCESS_DETACHn "), dwThreadId);
OutputDebugString(szLog);
}
break;
}
return TRUE;
}
#include " stdafx.h "
#include <tchar.h>
#include <stdio.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
const int kBuffLen = 256;
TCHAR szLog[kBuffLen];
DWORD dwThreadId = ::GetCurrentThreadId();
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
_stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_PROCESS_ATTACHn "), dwThreadId);
OutputDebugString(szLog);
}
break;
case DLL_THREAD_ATTACH:
{
_stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_THREAD_ATTACHn "), dwThreadId);
OutputDebugString(szLog);
}
break;
case DLL_THREAD_DETACH:
{
_stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_THREAD_DETACHn "), dwThreadId);
OutputDebugString(szLog);
}
break;
case DLL_PROCESS_DETACH:
{
_stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_PROCESS_DETACHn "), dwThreadId);
OutputDebugString(szLog);
}
break;
}
return TRUE;
}
应用程序工程,包含DLL的lib库,引用Foo()
/*
验证一下DllMain()的执行线程
验证结果:
DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH由主线程执行
DLL_THREAD_ATTACH/DLL_THREAD_DETACH由创建和消亡的线程执行
*/
#include <Windows.h>
#include <tchar.h>
#pragma comment(lib, "../Debug/DLLMainDLL.lib")
void Foo();
void Bar()
{
// 调用一下DLL的函数,使DLL链接进EXE的import table
Foo();
}
DWORD WINAPI ThreadFunc(LPVOID lpParam)
{
const int kBuffLen = 256;
TCHAR szLog[kBuffLen];
_stprintf_s(szLog, kBuffLen, _T( " [EXE] Thread(%d) execute ThreadFunc()n "), ::GetCurrentThreadId());
OutputDebugString(szLog);
::Sleep( 500);
_stprintf_s(szLog, kBuffLen, _T( " [EXE] Thread(%d) exit ThreadFunc()n "), ::GetCurrentThreadId());
OutputDebugString(szLog);
return 0;
}
int _tmain()
{
const int kBuffLen = 256;
TCHAR szLog[kBuffLen];
// 主线程
DWORD dwMainThreadId = ::GetCurrentThreadId();
_stprintf_s(szLog, kBuffLen, _T( " [EXE] MainThread(%d) execute main()n "), dwMainThreadId);
OutputDebugString(szLog);
// 新建线程
HANDLE hThread = NULL;
DWORD dwThreadId = 0;
hThread = ::CreateThread(NULL, 0, ThreadFunc, NULL, 0, &dwThreadId);
_stprintf_s(szLog, kBuffLen, _T( " [EXE] Create a new thread(%d)n "), dwThreadId);
OutputDebugString(szLog);
::WaitForSingleObject(hThread, INFINITE);
::CloseHandle(hThread);
hThread = NULL;
_stprintf_s(szLog, kBuffLen, _T( " [EXE] Thread(%d) is destroyedn "), dwThreadId);
OutputDebugString(szLog);
::Sleep( 500);
_stprintf_s(szLog, kBuffLen, _T( " [EXE] MainThread(%d) exit main()n "), dwMainThreadId);
OutputDebugString(szLog);
return 0;
}
验证一下DllMain()的执行线程
验证结果:
DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH由主线程执行
DLL_THREAD_ATTACH/DLL_THREAD_DETACH由创建和消亡的线程执行
*/
#include <Windows.h>
#include <tchar.h>
#pragma comment(lib, "../Debug/DLLMainDLL.lib")
void Foo();
void Bar()
{
// 调用一下DLL的函数,使DLL链接进EXE的import table
Foo();
}
DWORD WINAPI ThreadFunc(LPVOID lpParam)
{
const int kBuffLen = 256;
TCHAR szLog[kBuffLen];
_stprintf_s(szLog, kBuffLen, _T( " [EXE] Thread(%d) execute ThreadFunc()n "), ::GetCurrentThreadId());
OutputDebugString(szLog);
::Sleep( 500);
_stprintf_s(szLog, kBuffLen, _T( " [EXE] Thread(%d) exit ThreadFunc()n "), ::GetCurrentThreadId());
OutputDebugString(szLog);
return 0;
}
int _tmain()
{
const int kBuffLen = 256;
TCHAR szLog[kBuffLen];
// 主线程
DWORD dwMainThreadId = ::GetCurrentThreadId();
_stprintf_s(szLog, kBuffLen, _T( " [EXE] MainThread(%d) execute main()n "), dwMainThreadId);
OutputDebugString(szLog);
// 新建线程
HANDLE hThread = NULL;
DWORD dwThreadId = 0;
hThread = ::CreateThread(NULL, 0, ThreadFunc, NULL, 0, &dwThreadId);
_stprintf_s(szLog, kBuffLen, _T( " [EXE] Create a new thread(%d)n "), dwThreadId);
OutputDebugString(szLog);
::WaitForSingleObject(hThread, INFINITE);
::CloseHandle(hThread);
hThread = NULL;
_stprintf_s(szLog, kBuffLen, _T( " [EXE] Thread(%d) is destroyedn "), dwThreadId);
OutputDebugString(szLog);
::Sleep( 500);
_stprintf_s(szLog, kBuffLen, _T( " [EXE] MainThread(%d) exit main()n "), dwMainThreadId);
OutputDebugString(szLog);
return 0;
}
执行结果:
在VC的控制台输出:
[DLL] Thread(1644) execute DLL_PROCESS_ATTACH
[EXE] MainThread(1644) execute main()
[EXE] Create a new thread(5816)
[DLL] Thread(5816) execute DLL_THREAD_ATTACH
[EXE] Thread(5816) execute ThreadFunc()
[EXE] Thread(5816) exit ThreadFunc()
[DLL] Thread(5816) execute DLL_THREAD_DETACH
[EXE] Thread(5816) is destroyed
[EXE] MainThread(1644) exit main()
[DLL] Thread(1644) execute DLL_PROCESS_DETACH
结果分析:
1)应用程序主线程执行DllMain(),通知DLL_PROCESS_ATTACH
[DLL] Thread(1644) execute DLL_PROCESS_ATTACH
2)应用程序主线程执行main()
[EXE] MainThread(1644) execute main()
3)程序中新建线程,为已加载的DLL执行DllMain(),通知DLL_THREAD_ATTACH
[EXE] Create a new thread(5816)
[DLL] Thread(5816) execute DLL_THREAD_ATTACH
4)线程执行线程函数
[EXE] Thread(5816) execute ThreadFunc()
5)线程退出线程函数
[EXE] Thread(5816) exit ThreadFunc()
6)线程为已加载的DLL执行DllMain(),通知DLL_THREAD_DETACH
[DLL] Thread(5816) execute DLL_THREAD_DETACH
[EXE] Thread(5816) is destroyed
7)应用程序主线程退出main()
[EXE] MainThread(1644) exit main()
8)应用程序主线程执行DllMain(),通知DLL_PROCESS_DETACH
[DLL] Thread(1644) execute DLL_PROCESS_DETACH
转载于:https://www.cnblogs.com/shokey520/p/3673715.html
最后
以上就是风中含羞草为你收集整理的DllMain的执行线程的全部内容,希望文章能够帮你解决DllMain的执行线程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复