DLL学习(3)

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

例子:
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
 switch (ul_reason_for_call)
 {
  case DLL_PROCESS_ATTACH:
   printf("\nprocess attach of dll");
   break;
  case DLL_THREAD_ATTACH:
   printf("\nthread attach of dll");
   break;
  case DLL_THREAD_DETACH:
   printf("\nthread detach of dll");
   break;
  case DLL_PROCESS_DETACH:
   printf("\nprocess detach of dll");
   break;
 }
 return TRUE;
}

注:
1)APIENTRY被定义为__stdcall,它意味着这个函数以标准Pascal的方式进行调用,也就是WINAPI方式;
2)进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识,只有在特定的进程内部有效,句柄代表了DLL模块在进程虚拟空间
中的起始地址。在Win32中,HINSTANCE和HMODULE的值是相同的,这两种类型可以替换使用,这就是函数参数hModule的来历。

常见宏定义:
#define CALLBACK __stdcall //这就是传说中的回调函数
#define WINAPI __stdcall   //这就是传说中的WINAPI
#define WINAPIV __cdecl
#define APIENTRY WINAPI   //DllMain的入口就在这里
#define APIPRIVATE __stdcall
#define PASCAL __stdcall

C/C++缺省的调用方式却为__cdecl

如果生成的dll需要让其它语言调用则函数声明时要添加以下说明:
int __stdcall add(int x, int y);
typedef int(__stdcall *lpAddFun)(int, int);

你可能感兴趣的:(thread,c,windows,dos,pascal)