ML 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 code is needed only for Windows DLL initialization.
27// It is borrowed from 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#pragma once
32
33#ifndef WIN32_LEAN_AND_MEAN
34#define WIN32_LEAN_AND_MEAN // Do not include rarely used parts of windows header
35#endif
36
37#ifndef ML_SUPPRESS_LIBRARY_INIT_MACROS_WINDOWS_H_INCLUDE
38 #include <ThirdPartyWarningsDisable.h>
39 #include <windows.h>
40 #include <ThirdPartyWarningsRestore.h>
41#endif
42
43#endif // !defined(AFX_STDAFX_H__17533C48_9DB6_4FA8_AEC3_550E71AF7183__INCLUDED_)
44
45#endif // WIN32
46
47
48
49// Include normal ML runtime system and error handling code.
50#include "mlInitSystemML.h"
51#include "mlVersion.h"
52#include "mlErrorOutput.h"
53#include "mlErrorOutputInfos.h"
54#include "mlRuntime.h"
55
56#include "mlAPI.h"
57
59class RuntimeType;
60
63
64//--------------------------------------------------------------
79//--------------------------------------------------------------
80#define ML_LIBRARY_USER_DESTROY_CODE
81
82//--------------------------------------------------------------
95//--------------------------------------------------------------
96#ifdef WIN32
97
98// WIN32 case :
99// Macro to implement win32 DLL initialization function.
100// It is called after automatic instance initialization.
101#define ML_INIT_LIBRARY_EXT_3(initMethod, NAMESP, LIB_TARGET) \
102 BOOL APIENTRY DllMain( HANDLE /*hModule*/, \
103 DWORD ul_reason_for_call, \
104 LPVOID /*lpReserved*/ \
105 ) \
106 { \
107 \
108 switch (ul_reason_for_call){ \
109 case DLL_PROCESS_ATTACH: \
110 { \
111 /* Set the name of the init method as library name. */ \
112 ML_UTILS_NAMESPACE::Runtime::setRecentlyLoadedDllName(#LIB_TARGET); \
113 \
114 /* Check whether the ML C++ API has a valid version number so */ \
115 /* that the library can be linked safely. */ \
116 MLCheckCPPAPILinkCompatibility(ML_MAJOR_VERSION, \
117 ML_MAJOR_CAPI_VERSION, \
118 ML_CPPAPI_VERSION, \
119 ML_CAPI_REVISION, \
120 ML_VERSION_STRING, \
121 #initMethod); \
122 \
123 /* Call the initialization method of the library even on load */ \
124 /* failures. That function will usually register runtime types. */ \
125 /* It turned out that suppressing library init will cause more */ \
126 /* problems than trying it anyway. */ \
127 NAMESP::initMethod(); \
128 } \
129 break; \
130 case DLL_THREAD_ATTACH: \
131 break; \
132 case DLL_THREAD_DETACH: \
133 break; \
134 case DLL_PROCESS_DETACH: \
135 { \
136 /* Destroy all runtime types of the DLL with the name LIB_TARGET.*/ \
137 /* Do this only on explicit unloads to avoid undesired removal */ \
138 /* on normal process destruction where too many dependencies */ \
139 /* cause crashes. */ \
140 if (MLIsCurrentlyUnloadingLibrary()){ \
141 ML_LIBRARY_USER_DESTROY_CODE \
142 ML_UTILS_NAMESPACE::Runtime::destroyRuntimeTypesOfDll(#LIB_TARGET); \
143 } \
144 } \
145 break; \
146 } \
147 return TRUE; \
148 }
149
150#else
151
152// Linux case:
153// Macro to implement Linux shared object initialization function.
154// It is called after automatic instance initialization.
155#define ML_INIT_LIBRARY_EXT_3(initMethod, NAMESP, LIB_TARGET) \
156 extern "C" { \
157 extern int MLInit(int majorVersion, \
158 int majorCAPIVersion, \
159 int revCAPI); \
160 extern int MLIsCPPAPILinkCompatible(int majorVersion, \
161 int majorCAPIVersion, \
162 int verCPPAPI); \
163 } \
164 \
165 void initMethod##initDll() __attribute__ ((constructor)); \
166 void initMethod##initDll() \
167 { \
168 \
169 static bool initDone = false; \
170 if (!initDone) { \
171 /* On Linux we must guarantee that ML is initialized, because */ \
172 /* otherwise, global variables or singletons are still not */ \
173 /* valid for init class calls. We need to do that here */ \
174 /* because order of variable initialization and DLL */ \
175 /* initialization differs on Windows and Linux. */ \
176 MLInit(ML_MAJOR_VERSION, ML_MAJOR_CAPI_VERSION, ML_CAPI_REVISION); \
177 \
178 /* Set the name of the init method as library name. */ \
179 ML_UTILS_NAMESPACE::Runtime::setRecentlyLoadedDllName(#LIB_TARGET); \
180 \
181 /* Check whether the ML C++ API has a valid version number so */ \
182 /* that the library can be linked safely. */ \
183 MLCheckCPPAPILinkCompatibility(ML_MAJOR_VERSION, \
184 ML_MAJOR_CAPI_VERSION, \
185 ML_CPPAPI_VERSION, \
186 ML_CAPI_REVISION, \
187 ML_VERSION_STRING, \
188 #initMethod); \
189 \
190 /* Call the initialization method of the library even on load */ \
191 /* failures. That function will usually register runtime types. */ \
192 /* It turned out that suppressing library init will cause more */ \
193 /* problems than trying it anyway. */ \
194 NAMESP::initMethod(); \
195 initDone = true; \
196 } \
197 } \
198 \
199 /* This is the automatically implemented destruction */ \
200 /* function to clean up all RuntimeTypes related to this DLL. */ \
201 void initMethod##destroyDll() __attribute__ ((destructor)); \
202 void initMethod##destroyDll() \
203 { \
204 /* Destroy all runtime types of the DLL with the name LIB_TARGET.*/ \
205 /* Do this only on explicit unloads to avoid undesired removal */ \
206 /* on normal process destruction where too many dependencies */ \
207 /* cause crashes. */ \
208 if (MLIsCurrentlyUnloadingLibrary()){ \
209 ML_LIBRARY_USER_DESTROY_CODE \
210 ML_UTILS_NAMESPACE::Runtime::destroyRuntimeTypesOfDll(#LIB_TARGET); \
211 } \
212 } \
213 \
214
215#endif
216
217
218//--------------------------------------------------------------
222//--------------------------------------------------------------
223#define ML_INIT_LIBRARY(initMethod) \
224 _ML_INIT_LIBRARY_EXT_HELPER(initMethod, ML_UTILS_NAMESPACE, MEVIS_TARGET)
225
226//--------------------------------------------------------------
229//--------------------------------------------------------------
230#define ML_INIT_LIBRARY_EXT(initMethod, NAME_SP) \
231 _ML_INIT_LIBRARY_EXT_HELPER(initMethod, NAME_SP, MEVIS_TARGET)
232
233//--------------------------------------------------------------
240//--------------------------------------------------------------
241#define _ML_INIT_LIBRARY_EXT_HELPER(initMethod, NAME_SP, LIB_TARGET) \
242 ML_INIT_LIBRARY_EXT_2(initMethod, NAME_SP, LIB_TARGET)
243
244//--------------------------------------------------------------
247//--------------------------------------------------------------
248#ifndef ML_STATIC_BUILD
249#define ML_INIT_LIBRARY_EXT_2(initMethod, NAME_SP, LIB_TARGET) \
250 ML_INIT_LIBRARY_EXT_3(initMethod, NAME_SP, LIB_TARGET)
251#else
252#define ML_INIT_LIBRARY_EXT_2(initMethod, NAME_SP, LIB_TARGET)
253#endif
254
256
257#endif // __mlLibraryInitMacros_H
258
259