DLLMain
- 虽然DLL理论上不需要main函数,但是微软还是这么设计了
- 对于一个Dll模块,DllMain函数是可选的
- DELLmain 不会只执行一次
- 静态链接时,或动态链接时调用 都会调用DllMain函数
https://docs.microsoft.com/en-us/windows/desktop/dlls/dllmain
函数原型
BOOL WINAPI DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_ LPVOID lpvReserved
);
//相关函数
LoadLibrary 加载DLL
FreeLibrary 删除DLL
DLL_THREAD_ATTACH //某个线程使用DLL时
DLL_THREAD_DETACH //某个线程释放DLL时
DLL_PROCESS_ATTACH //第一次映射DLL时
DLL_PROCESS_DETACH //DLL最后一次释放后会发送这个型号
DLL_PROCESS_ATTACH
- 系统第一次将一个DLL映射到进程地址空间中时,会调用DllMain
- 只有在第一次映射的时候,才会这样。之后,另一线程再次显式加载此DLL,则操作系统只是增加该DLL的使用计数。
- 返回值 :对于隐式加载,如DllMain返回FALSE,则程序会启动失败。对于显式加载,则会使LoadLibrary返回NULL。
DLL_PROCESS_DETACH
- 系统将一个DLL从进程地址空间中撤销映射时,则会向DllMain传入DLL_PROCESS_DETACH。
当使用FreeLibrary时:
- 如该线程的使用计数为0时,操作系统才会使用DLL_PROCESS_DETACH来调用DllMain
- 如使用计数大于0,则只是单纯的减少该DLL的计数。
DLL_THREAD_ATTACH
- 进程创建一个线程,则系统会检查当前已映射到该进程空间中的所有DLL映像,并用DLL_THREAD_ATTACH来调用每个DLL的DllMain
- 当所有DLL都完成了对DLL_THREAD_ATTACH的处理后,新线程才会执行它的线程函数
DLL_THREAD_DETACH
- 线程若要终止,会调用ExitThread
- 但是此函数不会立即终止线程,而是会利用DLL_THREAD_DETACH来调用当前进程地址空间中的所有DLL镜像的DllMain。