MeVisLab Toolbox Reference
mlLibraryInitMacros.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2007, MeVis Medical Solutions AG
4 **
5 ** The user may use this file in accordance with the license agreement provided with
6 ** the Software or, alternatively, in accordance with the terms contained in a
7 ** written agreement between the user and MeVis Medical Solutions AG.
8 **
9 ** For further information use the contact form at https://www.mevislab.de/contact
10 **
11 **************************************************************************************/
12 
13 #ifndef ML_LIBRARY_INIT_MACROS_H
14 #define ML_LIBRARY_INIT_MACROS_H
15 
20 
21 #ifdef WIN32
22 
24 #pragma warning(disable : 4786 )
25 
26 // This stuff is needed only for windows DLL initialization.
27 // It is borrowed form VC++ automatic DLL project creation.
28 #if !defined(AFX_STDAFX_H__17533C48_9DB6_4FA8_AEC3_550E71AF7183__INCLUDED_)
29 #define AFX_STDAFX_H__17533C48_9DB6_4FA8_AEC3_550E71AF7183__INCLUDED_
30 
31 #if _MSC_VER > 1000
32 #pragma once
33 #endif // _MSC_VER > 1000
34 
35 #ifndef WIN32_LEAN_AND_MEAN
36 #define WIN32_LEAN_AND_MEAN // Do not include rarely used parts of windows header
37 #endif
38 
39 #ifndef ML_SUPPRESS_LIBRARY_INIT_MACROS_WINDOWS_H_INCLUDE
40  #include <ThirdPartyWarningsDisable.h>
41  #include <windows.h>
42  #include <ThirdPartyWarningsRestore.h>
43 #endif
44 
45 #endif // !defined(AFX_STDAFX_H__17533C48_9DB6_4FA8_AEC3_550E71AF7183__INCLUDED_)
46 
47 #endif // WIN32
48 
49 
50 
51 // Include normal ML runtime system and error handling stuff.
52 #include "mlInitSystemML.h"
53 #include "mlVersion.h"
54 #include "mlErrorOutput.h"
55 #include "mlErrorOutputInfos.h"
56 #include "mlRuntime.h"
57 
58 #include "mlAPI.h"
59 
61 class RuntimeType;
62 
65 
66 //--------------------------------------------------------------
81 //--------------------------------------------------------------
82 #define ML_LIBRARY_USER_DESTROY_CODE
83 
84 //--------------------------------------------------------------
97 //--------------------------------------------------------------
98 #ifdef WIN32
99 
100 // WIN32 case :
101 // Macro to implement win32 DLL initialization function.
102 // It is called after automatic instance initialization.
103 #define ML_INIT_LIBRARY_EXT_3(initMethod, NAMESP, LIB_TARGET) \
104  BOOL APIENTRY DllMain( HANDLE /*hModule*/, \
105  DWORD ul_reason_for_call, \
106  LPVOID /*lpReserved*/ \
107  ) \
108  { \
109  \
110  switch (ul_reason_for_call){ \
111  case DLL_PROCESS_ATTACH: \
112  { \
113  /* Set the name of the init method as library name. */ \
114  ML_UTILS_NAMESPACE::Runtime::setRecentlyLoadedDllName(#LIB_TARGET); \
115  \
116  /* Check whether the ML C++ API has a valid version number so */ \
117  /* that the library can be linked safely. */ \
118  MLCheckCPPAPILinkCompatibility(ML_MAJOR_VERSION, \
119  ML_MAJOR_CAPI_VERSION, \
120  ML_CPPAPI_VERSION, \
121  ML_CAPI_REVISION, \
122  ML_VERSION_STRING, \
123  #initMethod); \
124  \
125  /* Call the initialization method of the library even on load */ \
126  /* failures. That function will usually register runtime types. */ \
127  /* It turned out that suppressing library init will cause more */ \
128  /* problems than trying it anyway. */ \
129  NAMESP::initMethod(); \
130  } \
131  break; \
132  case DLL_THREAD_ATTACH: \
133  break; \
134  case DLL_THREAD_DETACH: \
135  break; \
136  case DLL_PROCESS_DETACH: \
137  { \
138  /* Destroy all runtime types of the dll with the name LIB_TARGET.*/ \
139  /* Do this only on explicit unloads to avoid undesired removal */ \
140  /* on normal process destruction where too many dependencies */ \
141  /* cause crashes. */ \
142  if (MLIsCurrentlyUnloadingLibrary()){ \
143  ML_LIBRARY_USER_DESTROY_CODE \
144  ML_UTILS_NAMESPACE::Runtime::destroyRuntimeTypesOfDll(#LIB_TARGET); \
145  } \
146  } \
147  break; \
148  } \
149  return TRUE; \
150  }
151 
152 #else
153 
154 // Linux case:
155 // Macro to implement Linux shared object initialization function.
156 // It is called after automatic instance initialization.
157 #define ML_INIT_LIBRARY_EXT_3(initMethod, NAMESP, LIB_TARGET) \
158  extern "C" { \
159  extern int MLInit(int majorVersion, \
160  int majorCAPIVersion, \
161  int revCAPI); \
162  extern int MLIsCPPAPILinkCompatible(int majorVersion, \
163  int majorCAPIVersion, \
164  int verCPPAPI); \
165  } \
166  \
167  void initMethod##initDll() __attribute__ ((constructor)); \
168  void initMethod##initDll() \
169  { \
170  \
171  static bool initDone = false; \
172  if (!initDone) { \
173  /* On Linux we must guarantee that ML is initialized, because */ \
174  /* otherwise global variables or singletons are still not */ \
175  /* valid for init class calls. We need to do that here */ \
176  /* because order of variable initialization and dll */ \
177  /* initialization differs on windows and Linux. */ \
178  MLInit(ML_MAJOR_VERSION, ML_MAJOR_CAPI_VERSION, ML_CAPI_REVISION); \
179  \
180  /* Set the name of the init method as library name. */ \
181  ML_UTILS_NAMESPACE::Runtime::setRecentlyLoadedDllName(#LIB_TARGET); \
182  \
183  /* Check whether the ML C++ API has a valid version number so */ \
184  /* that the library can be linked safely. */ \
185  MLCheckCPPAPILinkCompatibility(ML_MAJOR_VERSION, \
186  ML_MAJOR_CAPI_VERSION, \
187  ML_CPPAPI_VERSION, \
188  ML_CAPI_REVISION, \
189  ML_VERSION_STRING, \
190  #initMethod); \
191  \
192  /* Call the initialization method of the library even on load */ \
193  /* failures. That function will usually register runtime types. */ \
194  /* It turned out that suppressing library init will cause more */ \
195  /* problems than trying it anyway. */ \
196  NAMESP::initMethod(); \
197  initDone = true; \
198  } \
199  } \
200  \
201  /* This is the automatically implemented destruction */ \
202  /* function to clean up all RuntimeTypes related to this dll. */ \
203  void initMethod##destroyDll() __attribute__ ((destructor)); \
204  void initMethod##destroyDll() \
205  { \
206  /* Destroy all runtime types of the dll with the name LIB_TARGET.*/ \
207  /* Do this only on explicit unloads to avoid undesired removal */ \
208  /* on normal process destruction where too many dependencies */ \
209  /* cause crashes. */ \
210  if (MLIsCurrentlyUnloadingLibrary()){ \
211  ML_LIBRARY_USER_DESTROY_CODE \
212  ML_UTILS_NAMESPACE::Runtime::destroyRuntimeTypesOfDll(#LIB_TARGET); \
213  } \
214  } \
215  \
216 
217 #endif
218 
219 
220 //--------------------------------------------------------------
224 //--------------------------------------------------------------
225 #define ML_INIT_LIBRARY(initMethod) \
226  _ML_INIT_LIBRARY_EXT_HELPER(initMethod, ML_UTILS_NAMESPACE, MEVIS_TARGET)
227 
228 //--------------------------------------------------------------
231 //--------------------------------------------------------------
232 #define ML_INIT_LIBRARY_EXT(initMethod, NAME_SP) \
233  _ML_INIT_LIBRARY_EXT_HELPER(initMethod, NAME_SP, MEVIS_TARGET)
234 
235 //--------------------------------------------------------------
242 //--------------------------------------------------------------
243 #define _ML_INIT_LIBRARY_EXT_HELPER(initMethod, NAME_SP, LIB_TARGET) \
244  ML_INIT_LIBRARY_EXT_2(initMethod, NAME_SP, LIB_TARGET)
245 
246 //--------------------------------------------------------------
249 //--------------------------------------------------------------
250 #ifndef ML_STATIC_BUILD
251 #define ML_INIT_LIBRARY_EXT_2(initMethod, NAME_SP, LIB_TARGET) \
252  ML_INIT_LIBRARY_EXT_3(initMethod, NAME_SP, LIB_TARGET)
253 #else
254 #define ML_INIT_LIBRARY_EXT_2(initMethod, NAME_SP, LIB_TARGET)
255 #endif
256 
258 
259 #endif // __mlLibraryInitMacros_H
260 
261