ML Reference
MeVis/Foundation/Sources/ML/include/mlLibraryInitMacros.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //-------------------------------------------------------------------------
00012 //-------------------------------------------------------------------------
00013 #ifndef __mlLibraryInitMacros_H
00014 #define __mlLibraryInitMacros_H
00015 
00016 #ifdef WIN32
00017 
00019 #pragma warning(disable : 4786 )
00020 
00021 // This stuff is needed only for windows DLL initialization.
00022 // It is borrowed form VC++ automatic DLL project creation.
00023 #if !defined(AFX_STDAFX_H__17533C48_9DB6_4FA8_AEC3_550E71AF7183__INCLUDED_)
00024 #define AFX_STDAFX_H__17533C48_9DB6_4FA8_AEC3_550E71AF7183__INCLUDED_
00025 
00026 #if _MSC_VER > 1000
00027 #pragma once
00028 #endif // _MSC_VER > 1000
00029 
00030 #ifndef WIN32_LEAN_AND_MEAN
00031 #define WIN32_LEAN_AND_MEAN   // Do not include rarely used parts of windows header
00032 #endif
00033 
00034 #ifndef ML_SUPPRESS_LIBRARY_INIT_MACROS_WINDOWS_H_INCLUDE
00035   #include "mlSystemWarningsDisable.h"
00036   #include <windows.h>
00037   #include "mlSystemWarningsRestore.h"
00038 #endif
00039 
00040 #endif // !defined(AFX_STDAFX_H__17533C48_9DB6_4FA8_AEC3_550E71AF7183__INCLUDED_)
00041 
00042 #endif // WIN32
00043 
00044 
00045 
00046 // Include normal ML runtime system and error handling stuff.
00047 #ifndef __mlInitSystemML_H_PURE_C
00048 #include "mlInitSystemML.h"
00049 #endif
00050 #ifndef __mlVersion_H
00051 #include "mlVersion.h"
00052 #endif
00053 #ifndef __mlErrorOutput_H
00054 #include "mlErrorOutput.h"
00055 #endif
00056 #ifndef __mlErrorOutputInfos_H
00057 #include "mlErrorOutputInfos.h"
00058 #endif
00059 #ifndef __mlRuntime_H
00060 #include "mlRuntime.h"
00061 #endif
00062 
00063 #include "mlAPI.h"
00064 
00066 class RuntimeType;
00067 
00069 
00070 
00071 //--------------------------------------------------------------
00084 //--------------------------------------------------------------
00085 #ifdef WIN32
00086 
00087 // WIN32 case :
00088 // Macro to implement win32 DLL initialization function.
00089 // It is called after automatic instance initialization.
00090 #define ML_INIT_LIBRARY_EXT_2(initMethod, NAMESP, LIB_TARGET)               \
00091   BOOL APIENTRY DllMain( HANDLE /*hModule*/,                                \
00092                          DWORD  ul_reason_for_call,                         \
00093                          LPVOID /*lpReserved*/                              \
00094                        )                                                    \
00095   {                                                                         \
00096     ML_TRACE_IN( "DllMain" );                                               \
00097                                                                             \
00098     switch (ul_reason_for_call){                                            \
00099     case DLL_PROCESS_ATTACH:                                                \
00100     {                                                                       \
00101       /* Set the name of the init method as library name.   */              \
00102       ML_UTILS_NAMESPACE::Runtime::setRecentlyLoadedDllName(#LIB_TARGET);   \
00103                                                                             \
00104       /* Check whether the ML C++ API has a valid version number so */      \
00105       /* that the library can be linked safely.                     */      \
00106       MLCheckCPPAPILinkCompatibility(ML_MAJOR_VERSION,                      \
00107                                      ML_MAJOR_CAPI_VERSION,                 \
00108                                      ML_CPPAPI_VERSION,                     \
00109                                      ML_CAPI_REVISION,                      \
00110                                      ML_VERSION_STRING,                     \
00111                                      #initMethod);                          \
00112                                                                             \
00113       /* Call the initialization method of the library even on load   */    \
00114       /* failures. That function will usually register runtime types. */    \
00115       /* It turned out that suppressing library init will cause more  */    \
00116       /* problems than trying it anyway.                              */    \
00117       NAMESP::initMethod();                                                 \
00118     }                                                                       \
00119     break;                                                                  \
00120     case DLL_THREAD_ATTACH:                                                 \
00121     break;                                                                  \
00122     case DLL_THREAD_DETACH:                                                 \
00123     break;                                                                  \
00124     case DLL_PROCESS_DETACH:                                                \
00125     {                                                                       \
00126       ML_TRACE_IN( "_destroyMethod##initDll()" );                           \
00127       /* Destroy all runtime types of the dll with the name LIB_TARGET.*/   \
00128       /* Do this only on explicit unloads to avoid undesired removal   */   \
00129       /* on normal process destruction where too many dependencies     */   \
00130       /* cause crashes.                                                */   \
00131       if (MLIsCurrentlyUnloadingLibrary()){                                 \
00132         ML_UTILS_NAMESPACE::Runtime::destroyRuntimeTypesOfDll(#LIB_TARGET); \
00133       }                                                                     \
00134     }                                                                       \
00135     break;                                                                  \
00136     }                                                                       \
00137     return TRUE;                                                            \
00138   }
00139 
00140 #else
00141 
00142 // Linux case:
00143 // Macro to implement Linux shared object initialization function.
00144 // It is called after automatic instance initialization.
00145 #define ML_INIT_LIBRARY_EXT_2(initMethod, NAMESP, LIB_TARGET)             \
00146   extern "C" {                                                            \
00147     extern int MLInit(int majorVersion,                                   \
00148                       int majorCAPIVersion,                               \
00149                       int revCAPI);                                       \
00150     extern int MLIsCPPAPILinkCompatible(int majorVersion,                 \
00151                                         int majorCAPIVersion,             \
00152                                         int verCPPAPI);                   \
00153   }                                                                       \
00154                                                                           \
00155   void initMethod##initDll() __attribute__ ((constructor));               \
00156   void initMethod##initDll()                                              \
00157   {                                                                       \
00158     ML_TRACE_IN( "initMethod##initDll()" );                               \
00159                                                                           \
00160     static bool initDone = false;                                         \
00161     if (!initDone) {                                                      \
00162       /* On Linux we must guarantee that ML is initialized, because */    \
00163       /* otherwise global variables or singletons are still not     */    \
00164       /* valid for init class calls. We need to do that here        */    \
00165       /* because order of variable initialization and dll           */    \
00166       /* initialization differs on windows and Linux.               */    \
00167       MLInit(ML_MAJOR_VERSION, ML_MAJOR_CAPI_VERSION, ML_CAPI_REVISION);  \
00168                                                                           \
00169       /* Set the name of the init method as library name.   */            \
00170       ML_UTILS_NAMESPACE::Runtime::setRecentlyLoadedDllName(#LIB_TARGET); \
00171                                                                           \
00172       /* Check whether the ML C++ API has a valid version number so */    \
00173       /* that the library can be linked safely.                     */    \
00174       MLCheckCPPAPILinkCompatibility(ML_MAJOR_VERSION,                    \
00175                                      ML_MAJOR_CAPI_VERSION,               \
00176                                      ML_CPPAPI_VERSION,                   \
00177                                      ML_CAPI_REVISION,                    \
00178                                      ML_VERSION_STRING,                   \
00179                                      #initMethod);                        \
00180                                                                           \
00181       /* Call the initialization method of the library even on load   */  \
00182       /* failures. That function will usually register runtime types. */  \
00183       /* It turned out that suppressing library init will cause more  */  \
00184       /* problems than trying it anyway.                              */  \
00185       NAMESP::initMethod();                                               \
00186       initDone = true;                                                    \
00187     }                                                                     \
00188   }                                                                       \
00189                                                                           \
00190   /* This is the automatically implemented destruction              */    \
00191   /* function to clean up all RuntimeTypes related to this dll.     */    \
00192   void initMethod##destroyDll() __attribute__ ((destructor));          \
00193   void initMethod##destroyDll()                                        \
00194   {                                                                       \
00195     ML_TRACE_IN( "initMethod##destroyDll()" );                           \
00196     /* Destroy all runtime types of the dll with the name LIB_TARGET.*/   \
00197     /* Do this only on explicit unloads to avoid undesired removal   */   \
00198     /* on normal process destruction where too many dependencies     */   \
00199     /* cause crashes.                                                */   \
00200     if (MLIsCurrentlyUnloadingLibrary()){                                 \
00201       ML_UTILS_NAMESPACE::Runtime::destroyRuntimeTypesOfDll(#LIB_TARGET); \
00202     }                                                                     \
00203   }                                                                       \
00204                                                                           \
00205 
00206 #endif
00207 
00208 
00209 //--------------------------------------------------------------
00213 //--------------------------------------------------------------
00214 #define ML_INIT_LIBRARY(initMethod) \
00215   _ML_INIT_LIBRARY_EXT_HELPER(initMethod, ML_UTILS_NAMESPACE, MEVIS_TARGET)
00216 
00217 //--------------------------------------------------------------
00220 //--------------------------------------------------------------
00221 #define ML_INIT_LIBRARY_EXT(initMethod, NAME_SP) \
00222   _ML_INIT_LIBRARY_EXT_HELPER(initMethod, NAME_SP, MEVIS_TARGET)
00223 
00224 //--------------------------------------------------------------
00231 //--------------------------------------------------------------
00232 #define _ML_INIT_LIBRARY_EXT_HELPER(initMethod, NAME_SP, LIB_TARGET) \
00233   ML_INIT_LIBRARY_EXT_2(initMethod, NAME_SP, LIB_TARGET)
00234 
00236 
00237 #endif  // __mlLibraryInitMacros_H
00238 
00239