Share

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 as WaitForSingleObject
  • 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's HINSTANCE, and call DisableThreadLibraryCalls() if nothing special needs to be done during DLL_THREAD_ATTACH and DLL_THREAD_DETACH.

  • All the InitCommon* are now 'obsolete' -- calling them does nothing, and core.dll simply works for everyone

  • If 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).

Was this information helpful?