ML Reference
|
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