DllMain的执行线程

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_ATTACH\n "), dwThreadId);
            OutputDebugString(szLog);
        }
         break;
     case DLL_THREAD_ATTACH:
        {
            _stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_THREAD_ATTACH\n "), dwThreadId);
            OutputDebugString(szLog);
        }
         break;
     case DLL_THREAD_DETACH:
        {
            _stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_THREAD_DETACH\n "), dwThreadId);
            OutputDebugString(szLog);
        }
         break;
     case DLL_PROCESS_DETACH:
        {
            _stprintf_s(szLog, kBuffLen, _T( " [DLL] Thread(%d) execute DLL_PROCESS_DETACH\n "), 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 destroyed\n "), 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值