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 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
61class 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