Changes to DllMain()
Writing correct DllMain() functions is difficult. MSDN describes a series of restrictions, but these are so often ignored that Microsoft had to relax these restrictions by adding IJW ("It Just Works") technology.
Briefly, the following are all disallowed within a DllMain():
- Call into another DLL, except functions in
kernel32.dll - Directly, or indirectly, call
FreeLibrary, LoadLibrary,LoadLibraryEx - Perform synchronization between objects, using any of the
Waitfunctions, such asWaitForSingleObject - Throw an exception
In C++, this also applies to global C++ objects, which are constructed just before DllMain(DLL_PROCESS_ATTACH) is called, and destroyed just after DllMain(DLL_PROCESS_DETACH) is called.
A majority of 3ds Max plug-ins violated one or more of these "rules", but worked properly because of IJW. With VS2005, we made the following changes:
DllMain()doesn't do anything anymore, except keep the DLL'sHINSTANCE, and callDisableThreadLibraryCalls()if nothing special needs to be done duringDLL_THREAD_ATTACHandDLL_THREAD_DETACH.All the
InitCommon* are now 'obsolete' -- calling them does nothing, andcore.dll simply works for everyoneIf a DLL still requires special initialization and cleanup, then it should do so in one of the two following functions:
__declspec( dllexport ) int LibInitialize(void); __declspec( dllexport ) intLibShutdown(void);
These should be called only once each, but it is not strictly enforced; the functions must keep track of this. Changes will also have to be done in the module definition files (*.DEF) to take these two functions into account. See Changes to Module Definition Files(.DEF).
