DLL入口点DllMain函数:
DLL入口点函数DllMain,通常被用来执行一些与进程或者线程有关的初始化和清理工作。如果不需要,则可以在源代码中不去实现。DllMain函数执行的时候,同一个地址空间的其它DLL可能还没有执行它们的DllMain,因为我们应该避免调用那些从其它DLL中导入的函数。
DLL入口点通知:
当系统第一次且只有一次将DLL映射到进程地址空间中,会调用DllMain函数并传入DLL_PROCESS_ATTACH,执行与进程相关的操作。系统不会让任何已有的线程用DLL_THREAD_ATTACH来调用该DLL的DllMain函数,只会让创建的新线程对已经映射到进程地址空间的DLL都用DLL_THREAD_ATTACH调用DLL的DllMain函数。系统不会让进程的主线程用DLL_THREAD_ATTACH值来调用DllMain函数,进程创建的时候被映射到进程地址空间的任何DLL会受到DLL_PROCESS_ATTACH通知,但是不会受到DLL_THREAD_ATTACH通知。
进程、线程创建和销毁发送通知:
进程创建,DLL被映射到进程地址空间或从进程地址空间卸载,分别发送DLL_PROCESS_ATTACH或DLL_PROCESS_DETACH通知调用DllMain函数;DLL已经被映射到进程地址空间,线程创建或销毁,分别发送DLL_THREAD_ATTACH或DLL_THREAD_DETACH通知调用DllMain函数。
DllMain和C/C++运行库:
生成DLL的时候,链接器会将DLL的入口点函数的地址嵌入到生成的DLL文件映像中。_DllMainCRTStartup入口点函数被静态地链接到DLL文件映像中,而不关心使用的C/C++运行库版本。_DllMainCRTStartup会将所有通知转发到__DllMainCRTStartup函数,它会初始化C/C++运行库,并确保_DllMainCRTStartup收到通知的时候,所有全局或静态C++对象都已经构造完毕。然后再调用我们的DllMain函数。