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
Wait
functions, 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_ATTACH
andDLL_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).