-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdbj-dllimp.h
65 lines (53 loc) · 2.56 KB
/
dbj-dllimp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#ifndef DBJ_COMPONENT_INCLUDED
#define DBJ_COMPONENT_INCLUDED
/* (c) 2019 - 2021 by dbj.org -- https://dbj.org/license_dbj
*/
#include "dbj-dll.h"
// dbj-component working or not in the presence of MT is left to the
// requirements, ie. it is not controlled by dbj dll component design
DBJ_EXTERN_C_BEGIN
// dbj_dll_component_can_unload_now is part of each dbj-component definition
// use this macro to implement it inside a component dll
// dbj_dll_component_can_unload_now() is required by dbj-component-loader
#define DBJ_COMPONENT_UNLOADER_IMPLEMENTATION(...) \
static volatile long component_counter_ = 0; \
\
__attribute__((constructor)) static void component_ctor(void) { \
_InterlockedIncrement(&component_counter_); \
} \
\
__attribute__((destructor)) static void component_dtor() { \
_InterlockedDecrement(&component_counter_); \
} \
bool DBJCS_CAN_UNLOAD_NOW_FUN(void) { return component_counter_ == 0; }
#pragma region component semver
// each dbj-component has to exhibit semantic versioning 3 values
// and description string up to 0xFF chars long
// this structure is required for client code
struct dbj_component_version_ {
unsigned major;
unsigned minor;
unsigned patch;
char description[0xFF];
};
// use this macro to implement versioning inside a component
#define DBJ_COMPONENT_VERSION_IMPLEMENTATION(MA_, MI_, PA_, S_) \
struct dbj_component_version_ DBJCS_COMPONENT_VERSION_FUN(void) { \
static struct dbj_component_version_ the_version_ = {MA_, MI_, PA_, {0}}; \
if (0 == the_version_.description[0]) { \
strcpy_s(the_version_.description, 0xFF, S_); \
} \
return the_version_; \
}
#pragma endregion // component semver
/*
function footprints for these two are always the same
for them to be used client code need funcion pointer
declarations
thus these two are always the same and declared in here
and nowehere else
*/
typedef struct dbj_component_version_ (*DBJ_COMPONENT_SEMVER_FP)(void);
typedef bool (*DBJ_COMPONENT_UNLOAD_FP)(void);
DBJ_EXTERN_C_END
#endif // DBJ_COMPONENT_INCLUDED