我是靠谱客的博主 风中含羞草,最近开发中收集的这篇文章主要介绍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_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;
}

 

执行结果:

在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的执行线程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部