-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathdylib.hpp
91 lines (75 loc) · 2.29 KB
/
dylib.hpp
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#pragma once
#if defined(_MSC_VER)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#else
#include <dlfcn.h>
#endif
class DynamicLibrary
{
public:
DynamicLibrary() : handle(nullptr)
{
}
~DynamicLibrary()
{
if (handle != nullptr)
{
#if defined(_MSC_VER)
FreeLibrary(static_cast<HINSTANCE>(handle));
#else
dlclose(handle);
#endif
}
}
bool try_load(const char *library)
{
#if defined(_MSC_VER)
handle = static_cast<void *>(LoadLibraryA(library));
if (handle == nullptr)
{
handle = static_cast<void *>(LoadLibraryExA(library, NULL,
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR));
}
#else
handle = dlopen(library, RTLD_NOW);
#endif
return handle != nullptr;
}
bool LibraryIsLoaded() const
{
return handle != nullptr;
}
void *get_symbol(const char *name)
{
#if defined(_MSC_VER)
FARPROC function_address = GetProcAddress(static_cast<HINSTANCE>(handle), name);
#else
void *function_address = dlsym(handle, name);
#endif
return reinterpret_cast<void *>(function_address);
}
private:
void *handle = nullptr;
};
// Next we will introduce some magic macros to declare function pointers and load them from dynamic
// library robustly
#define DYLIB_EXTERN_DECLARE(f) extern decltype(&::f) f
#define DYLIB_DECLARE(f) decltype(&::f) f = nullptr
#define DYLIB_LOAD_INIT \
ankerl::unordered_dense::map<std::string, void *> _function_pointers; \
bool _load_success = true
#define DYLIB_LOAD_FUNCTION(f) \
{ \
auto ptr = reinterpret_cast<decltype(f)>(lib.get_symbol(#f)); \
if (ptr == nullptr) \
{ \
fmt::print("function {} is not loaded correctly\n", #f); \
_load_success = false; \
} \
_function_pointers[#f] = reinterpret_cast<void *>(ptr); \
}
#define IS_DYLIB_LOAD_SUCCESS _load_success
#define DYLIB_SAVE_FUNCTION(f) f = reinterpret_cast<decltype(f)>(_function_pointers[#f])