DllMain函数

Windows在加载DLL的时候,需要一个入口函数,就如同控制台或DOS程序需要main函数、WIN32程序需要WinMain函数一样。在前面的例子中,DLL并没有提供DllMain函数,应用工程也能成功引用DLL,这是因为Windows在找不到DllMain的时候,系统会从其它运行库中引入一个不做任何操作的缺省DllMain函数版本,并不意味着DLL可以放弃DllMain函数。

  根据编写规范,Windows必须查找并执行DLL里的DllMain函数作为加载DLL的依据,它使得DLL得以保留在内存里。这个函数并不属于导出函数,而是DLL的内部函数。这意味着不能直接在应用工程中引用DllMain函数,DllMain是自动被调用的。

  我们来看一个DllMain函数的例子(单击此处下载本工程附件)。
 1 BOOL APIENTRY DllMain( HANDLE hModule, 
2 DWORD ul_reason_for_call,
3 LPVOID lpReserved
4 )
5 {
6 switch (ul_reason_for_call)
7 {
8 case DLL_PROCESS_ATTACH:
9 printf("\nprocess attach of dll");
10 break;
11 case DLL_THREAD_ATTACH:
12 printf("\nthread attach of dll");
13 break;
14 case DLL_THREAD_DETACH:
15 printf("\nthread detach of dll");
16 break;
17 case DLL_PROCESS_DETACH:
18 printf("\nprocess detach of dll");
19 break;
20 }
21 return TRUE;
22 }


  DllMain函数在DLL被加载和卸载时被调用,在单个线程启动和终止时,DLLMain函数也被调用,ul_reason_for_call指明了被调用的原因。原因共有4种,即PROCESS_ATTACH、PROCESS_DETACH、THREAD_ATTACH和THREAD_DETACH,以switch语句列出。
来仔细解读一下DllMain的函数头BOOL APIENTRY DllMain( HANDLE hModule, WORD ul_reason_for_call, LPVOID lpReserved )。

  APIENTRY被定义为__stdcall,它意味着这个函数以标准Pascal的方式进行调用,也就是WINAPI方式;

  进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识,只有在特定的进程内部有效,句柄代表了DLL模块在进程虚拟空间中的起始地址。在Win32中,HINSTANCE和HMODULE的值是相同的,这两种类型可以替换使用,这就是函数参数hModule的来历。

  执行下列代码:
 1 hDll = LoadLibrary("..\\Debug\\dllTest.dll");
2 if (hDll != NULL)
3 {
4 addFun = (lpAddFun)GetProcAddress(hDll, MAKEINTRESOURCE(1));
5 //MAKEINTRESOURCE直接使用导出文件中的序号
6 if (addFun != NULL)
7 {
8 int result = addFun(2, 3);
9 printf("\ncall add in dll:%d", result);
10 }
11 FreeLibrary(hDll);
12 }


  我们看到输出顺序为:

  process attach of dll

  call add in dll:5

  process detach of dll

  这一输出顺序验证了DllMain被调用的时机。

  代码中的GetProcAddress ( hDll, MAKEINTRESOURCE ( 1 ) )值得留意,它直接通过.def文件中为add函数指定的顺序号访问add函数,具体体现在MAKEINTRESOURCE ( 1 ),MAKEINTRESOURCE是一个通过序号获取函数名的宏,定义为(节选自winuser.h):
 1 #define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i)))
2
3 #define MAKEINTRESOURCEW(i) (LPWSTR)((DWORD)((WORD)(i)))
4
5 #ifdef UNICODE
6
7 #define MAKEINTRESOURCE MAKEINTRESOURCEW
8
9 #else
10
11 #define MAKEINTRESOURCE MAKEINTRESOURCEA

转自http://www.cppblog.com/ivenher/articles/1315.html
posted @ 2011-12-23 21:24  bamb00  阅读(1311)  评论(0编辑  收藏  举报