Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1619696
  • 博文数量: 441
  • 博客积分: 20087
  • 博客等级: 上将
  • 技术积分: 3562
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-19 15:35
文章分类

全部博文(441)

文章存档

2014年(1)

2012年(1)

2011年(8)

2010年(16)

2009年(15)

2008年(152)

2007年(178)

2006年(70)

分类: C/C++

2008-10-24 12:11:43

如果一个新的进程或者线程使用了我的DLL, 那么我是如何知道的呢?
任何时候, 当一个进程或者线程载入或者卸载一个DLL的时候, DllMain函数都会被调用,并且DllMain获得载入和卸载的消息, 如果是进程加载DLL, 那么DllMain会收到DLL_PROCESS_ATTACH, 如果进程卸载DLL, DllMain会收到DLL_PROCESS_DETACH, 同样的,线程也会在加载卸载的时候, DllMain会收到DLL_THTREAD_ATTACH和DLL_THREAD_DETACH消息。下面的程序演示了这一现象:


// Entry.c


#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved)
{
    DWORD tid = GetCurrentThreadId();
    switch ( dwReason )
    {
    case DLL_PROCESS_ATTACH:
        printf("DLL:\tProcess attach (tid=%d)\n", tid);
        break;
    case DLL_THREAD_ATTACH:
        printf("DLL:\tThread attach (tid=%d)\n", tid);
        break;
    case DLL_THREAD_DETACH:
        printf("DLL:\tThread detach (tid=%d)\n", tid);
        break;
    case DLL_PROCESS_DETACH:
        printf("DLL:\tProcess detach (tid=%d)\n", tid);
        break;
    }

    return TRUE;
}

 __declspec(dllexport) BOOL TheFunction()
{
    printf("DLL: TheFunction() called.\n");
    return TRUE;
}


上面的程序是一个win32的dll, 你可以在VC6++中新建一个win32 dll的空工程,把上面的文件加入,编译后生成Entry.dll文件,同时还有一个库文件Entry.lib。

在建立一个win32的应用程序的空工程, 加入以下代码测试DLL:


// EntryDllTest.c


#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


__declspec(dllimport) BOOL TheFunction();

DWORD WINAPI ThreadFunc(LPVOID lpParam);

int main()
{
    HANDLE hThread = NULL;

    printf("Call TheFunction() in main:\n");
    TheFunction();

    hThread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
    if ( hThread == NULL )
        return -1;
    
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);

    return 0;
}

DWORD WINAPI ThreadFunc(LPVOID lpParam)
{
    UNREFERENCED_PARAMETER(lpParam);

    printf("xxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
    printf("Call TheFunction() in Thread: \n");
    TheFunction();
    printf("xxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
    

    return 0;
}


编译的时候, 需要把Entry.dll拷贝到debug目录, 同时把Entry.lib拷贝到工程目录, 并且在Project Settings的link选项卡中,在Object/Library modules中加入Entry.lib库。

下面是运行结果:
DLL:    Process attach (tid=4092)
Call TheFunction() in main:
DLL: TheFunction() called.
DLL:    Thread attach (tid=3888)
xxxxxxxxxxxxxxxxxxxxxxxxxxx
Call TheFunction() in Thread:
DLL: TheFunction() called.
xxxxxxxxxxxxxxxxxxxxxxxxxxx
DLL:    Thread detach (tid=3888)
DLL:    Process detach (tid=4092)
Press any key to continue

从运行结果上, 可以很明显的看出DLL被加载卸载的过程。
阅读(2126) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~