GNU libmicrohttpd
0.9.75
Loading...
Searching...
No Matches
autoinit_funcs.h
Go to the documentation of this file.
1
/*
2
* AutoinitFuncs: Automatic Initialization and Deinitialization Functions
3
* Copyright(C) 2014-2017 Karlson2k (Evgeny Grin)
4
*
5
* This header is free software; you can redistribute it and / or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
9
*
10
* This header is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
14
*
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this header; if not, see
17
* <http://www.gnu.org/licenses/>.
18
*/
19
20
/*
21
General usage is simple: include this header, declare or define two
22
functions with zero parameters (void) and any return type: one for
23
initialization and one for deinitialization, add
24
_SET_INIT_AND_DEINIT_FUNCS(FuncInitName, FuncDeInitName) to the code
25
and functions will be automatically called during application startup
26
and shutdown.
27
This is useful for libraries as libraries doesn't have direct access
28
to main() functions.
29
Example:
30
-------------------------------------------------
31
#include <stdlib.h>
32
#include "autoinit_funcs.h"
33
34
int someVar;
35
void* somePtr;
36
37
void libInit(void)
38
{
39
someVar = 3;
40
somePtr = malloc(100);
41
}
42
43
void libDeinit(void)
44
{
45
free(somePtr);
46
}
47
48
_SET_INIT_AND_DEINIT_FUNCS(libInit,libDeinit);
49
-------------------------------------------------
50
51
If initializer or deinitializer function is not needed, just define
52
it as empty function.
53
54
This header should work with GCC, clang, MSVC (2010 or later) and
55
SunPro / Sun Studio / Oracle Solaris Studio / Oracle Developer Studio
56
compiler.
57
Supported C and C++ languages; application, static and dynamic (DLL)
58
libraries; non-optimized (Debug) and optimized (Release) compilation
59
and linking.
60
61
For more information see header code and comments in code.
62
*/
63
#ifndef AUTOINIT_FUNCS_INCLUDED
64
#define AUTOINIT_FUNCS_INCLUDED 1
65
70
#define AUTOINIT_FUNCS_VERSION 0x01000200
71
72
#if defined(__GNUC__) || defined(__clang__)
73
/* if possible - check for supported attribute */
74
#ifdef __has_attribute
75
#if ! __has_attribute (constructor) || ! __has_attribute (destructor)
76
#define _GNUC_ATTR_CONSTR_NOT_SUPPORTED 1
77
#endif
/* !__has_attribute(constructor) || !__has_attribute(destructor) */
78
#endif
/* __has_attribute */
79
#endif
/* __GNUC__ */
80
81
/* "_attribute__ ((constructor))" is supported by GCC, clang and
82
Sun/Oracle compiler starting from version 12.1. */
83
#if ((defined(__GNUC__) || defined(__clang__)) && \
84
! defined(_GNUC_ATTR_CONSTR_NOT_SUPPORTED)) || \
85
(defined(__SUNPRO_C) && __SUNPRO_C + 0 >= 0x5100)
86
87
#define GNUC_SET_INIT_AND_DEINIT(FI,FD) \
88
void __attribute__ ((constructor)) _GNUC_init_helper_ ## FI (void) \
89
{ (void) (FI) (); } \
90
void __attribute__ ((destructor)) _GNUC_deinit_helper_ ## FD (void) \
91
{ (void) (FD) (); } \
92
struct _GNUC_dummy_str_ ## FI {int i;}
93
94
#define _SET_INIT_AND_DEINIT_FUNCS(FI,FD) GNUC_SET_INIT_AND_DEINIT (FI,FD)
95
#define _AUTOINIT_FUNCS_ARE_SUPPORTED 1
96
97
#elif defined (_MSC_FULL_VER) && _MSC_VER + 0 >= 1600
98
99
/* Make sure that your project/sources define:
100
_LIB if building a static library (_LIB is ignored if _CONSOLE is defined);
101
_USRDLL if building DLL-library;
102
not defined both _LIB and _USRDLL if building an application */
103
104
/* Define AUTOINIT_FUNCS_DECLARE_STATIC_REG if you need macro declaration
105
for registering static initialization functions even if you building DLL */
106
/* Define AUTOINIT_FUNCS_FORCE_STATIC_REG if you want to set main macro
107
_SET_INIT_AND_DEINIT_FUNCS to static version even if building a DLL*/
108
109
/* Stringify macros */
110
#define _INSTRMACRO(a) #a
111
#define _STRMACRO(a) _INSTRMACRO (a)
112
113
#if ! defined(_USRDLL) || defined(AUTOINIT_FUNCS_DECLARE_STATIC_REG)
114
115
/* required for atexit() */
116
#include <stdlib.h>
117
118
/* Use "C" linkage for variable to simplify variable decoration */
119
#ifdef __cplusplus
120
#define W32_INITVARDECL extern "C"
121
#else
122
#define W32_INITVARDECL extern
123
#endif
124
125
/* How variable is decorated by compiler */
126
#if defined(_M_X64) || defined(_M_AMD64)
127
#define W32_VARDECORPREFIX
128
#define W32_DECORVARNAME(v) v
129
#define W32_VARDECORPEFIXSTR ""
130
#elif defined(_M_IX86) || defined(_X86_)
131
#define W32_VARDECORPREFIX _
132
#define W32_DECORVARNAME(v) _ ## v
133
#define W32_VARDECORPEFIXSTR "_"
134
#else
135
#error Do not know how to decorate symbols for this architecture
136
#endif
137
138
/* Internal variable prefix (can be any) */
139
#define W32_INITHELPERVARNAME(f) _initHelperDummy_ ## f
140
#define W32_INITHELPERVARNAMEDECORSTR(f) W32_VARDECORPEFIXSTR _STRMACRO ( \
141
W32_INITHELPERVARNAME (f))
142
143
/* Declare section (segment), put variable pointing to init function to chosen segment,
144
force linker to include variable to avoid omitting by optimizer */
145
/* Initialization function must be declared as
146
int __cdecl FuncName(void) */
147
/* Return value is ignored for C++ initializers */
148
/* For C initializers: startup process is aborted if initializer return non-zero */
149
#define W32_FPTR_IN_SEG(S,F) \
150
__pragma (section (S,long,read)) \
151
__pragma (comment (linker, "/INCLUDE:"
W32_INITHELPERVARNAMEDECORSTR (F))) \
152
W32_INITVARDECL __declspec(allocate (S))int (__cdecl * W32_INITHELPERVARNAME ( \
153
F))(void) = &F
154
155
/* Section (segment) names for pointers to initializers */
156
#define W32_SEG_INIT_C_USER ".CRT$XCU"
157
#define W32_SEG_INIT_C_LIB ".CRT$XCL"
158
#define W32_SEG_INIT_CXX_USER ".CRT$XIU"
159
#define W32_SEG_INIT_CXX_LIB ".CRT$XIL"
160
161
/* Declare macro for different initializers sections */
162
/* Macro can be used several times to register several initializers */
163
/* Once function is registered as initializer, it will be called automatically
164
during application startup */
165
/* "lib" initializers are called before "user" initializers */
166
/* "C" initializers are called before "C++" initializers */
167
#define W32_REG_INIT_C_USER(F) W32_FPTR_IN_SEG (W32_SEG_INIT_C_USER,F)
168
#define W32_REG_INIT_C_LIB(F) W32_FPTR_IN_SEG (W32_SEG_INIT_C_LIB,F)
169
#define W32_REG_INIT_CXX_USER(F) W32_FPTR_IN_SEG (W32_SEG_INIT_CXX_USER,F)
170
#define W32_REG_INIT_CXX_LIB(F) W32_FPTR_IN_SEG (W32_SEG_INIT_CXX_LIB,F)
171
172
/* Choose main register macro based on language and program type */
173
/* Assuming that _LIB or _USRDLL is defined for static or DLL-library */
174
/* Macro can be used several times to register several initializers */
175
/* Once function is registered as initializer, it will be called automatically
176
during application startup */
177
/* Define AUTOINIT_FUNCS_FORCE_USER_LVL_INIT to register initializers
178
at user level even if building library */
179
#ifdef __cplusplus
180
#if ((defined(_LIB) && ! defined(_CONSOLE)) || defined(_USRDLL)) && \
181
! defined(AUTOINIT_FUNCS_FORCE_USER_LVL_INIT)
182
#define W32_REGISTER_INIT(F) W32_REG_INIT_CXX_LIB (F)
183
#else
/* ! _LIB && ! _DLL */
184
#define W32_REGISTER_INIT(F) W32_REG_INIT_CXX_USER (F)
185
#endif
/* ! _LIB && ! _DLL */
186
#else
/* !__cplusplus*/
187
#if ((defined(_LIB) && ! defined(_CONSOLE)) || defined(_USRDLL)) && \
188
! defined(AUTOINIT_FUNCS_FORCE_USER_LVL_INIT)
189
#define W32_REGISTER_INIT(F) W32_REG_INIT_C_LIB (F)
190
#else
/* ! _LIB && ! _DLL */
191
#define W32_REGISTER_INIT(F) W32_REG_INIT_C_USER (F)
192
#endif
/* ! _LIB && ! _DLL */
193
#endif
/* !__cplusplus*/
194
195
#else
/* _USRDLL */
196
197
#ifndef WIN32_LEAN_AND_MEAN
198
#define WIN32_LEAN_AND_MEAN 1
199
#endif
/* WIN32_LEAN_AND_MEAN */
200
/* Required for DllMain */
201
#include <Windows.h>
202
#endif
/* _USRDLL */
203
204
205
#if ! defined(_USRDLL) || defined(AUTOINIT_FUNCS_FORCE_STATIC_REG)
206
#define W32_SET_INIT_AND_DEINIT(FI,FD) \
207
void __cdecl _W32_deinit_helper_ ## FD (void) \
208
{ (void) (FD) (); } \
209
int __cdecl _W32_init_helper_ ## FI (void) \
210
{ (void) (FI) (); atexit (_W32_deinit_helper_ ## FD); return 0; } \
211
W32_REGISTER_INIT (_W32_init_helper_ ## FI)
212
#else
/* _USRDLL */
213
214
/* If DllMain is already present in code, define AUTOINIT_FUNCS_CALL_USR_DLLMAIN
215
and rename DllMain to usr_DllMain */
216
#ifndef AUTOINIT_FUNCS_CALL_USR_DLLMAIN
217
#define W32_SET_INIT_AND_DEINIT(FI,FD) \
218
BOOL WINAPI DllMain (HINSTANCE hinst,DWORD reason,LPVOID unused) \
219
{ if (DLL_PROCESS_ATTACH==reason) {(void) (FI) ();} \
220
else if (DLL_PROCESS_DETACH==reason) {(void) (FD) ();} \
221
return TRUE; \
222
} struct _W32_dummy_strc_ ## FI {int i;}
223
#else
/* AUTOINIT_FUNCS_CALL_USR_DLLMAIN */
224
#define W32_SET_INIT_AND_DEINIT(FI,FD) \
225
BOOL WINAPI usr_DllMain (HINSTANCE hinst,DWORD reason,LPVOID unused); \
226
BOOL WINAPI DllMain (HINSTANCE hinst,DWORD reason,LPVOID unused) \
227
{ if (DLL_PROCESS_ATTACH==reason) {(void) (FI) ();} \
228
else if (DLL_PROCESS_DETACH==reason) {(void) (FD) ();} \
229
return usr_DllMain (hinst,reason,unused); \
230
} struct _W32_dummy_strc_ ## FI {int i;}
231
#endif
/* AUTOINIT_FUNCS_CALL_USR_DLLMAIN */
232
#endif
/* _USRDLL */
233
234
#define _SET_INIT_AND_DEINIT_FUNCS(FI,FD) W32_SET_INIT_AND_DEINIT (FI,FD)
235
/* Indicate that automatic initializers/deinitializers are supported */
236
#define _AUTOINIT_FUNCS_ARE_SUPPORTED 1
237
238
#else
/* !__GNUC__ && !_MSC_FULL_VER */
239
240
/* Define EMIT_ERROR_IF_AUTOINIT_FUNCS_ARE_NOT_SUPPORTED before inclusion of header to
241
abort compilation if automatic initializers/deinitializers are not supported */
242
#ifdef EMIT_ERROR_IF_AUTOINIT_FUNCS_ARE_NOT_SUPPORTED
243
#error \
244
Compiler/platform don not support automatic calls of user-defined initializer and deinitializer
245
#endif
/* EMIT_ERROR_IF_AUTOINIT_FUNCS_ARE_NOT_SUPPORTED */
246
247
/* Do nothing */
248
#define _SET_INIT_AND_DEINIT_FUNCS(FI,FD)
249
/* Indicate that automatic initializers/deinitializers are not supported */
250
#define _AUTOINIT_FUNCS_ARE_NOT_SUPPORTED 1
251
252
#endif
/* !__GNUC__ && !_MSC_FULL_VER */
253
#endif
/* !AUTOINIT_FUNCS_INCLUDED */
src
include
autoinit_funcs.h
Generated by
1.9.7