PLaSK library
Loading...
Searching...
No Matches
loader.hpp
Go to the documentation of this file.
1/*
2 * This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3 * Copyright (c) 2022 Lodz University of Technology
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef PLASK__UTILS_DYNLIB_LOADER_H
15#define PLASK__UTILS_DYNLIB_LOADER_H
16
17#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
18# define PLASK__UTILS_PLUGIN_WINAPI
19#else
20# define PLASK__UTILS_PLUGIN_DLOPEN
21#endif
22
23#include <string>
24#include <functional> //std::hash
25
26#include <plask/config.hpp>
27
28namespace plask {
29
36
37 enum Flags {
38 DONT_CLOSE = 1
39 };
40
41 typedef void* handle_t; // real type on windows is HINSTANCE, but it is a pointer (to struct), so we are going to cast it from/to void* to avoid indluding windows.h
42
43private:
45 handle_t handle;
46#ifdef PLASK__UTILS_PLUGIN_WINAPI
47 bool unload; // true if lib. should be unloaded, destructor just don't call FreeLibrary if this is false, undefined when handle == 0
48#endif
49
50public:
51
58 handle_t getHandle() const { return handle; }
59
60 static constexpr const char* DEFAULT_EXTENSION =
61#ifdef PLASK__UTILS_PLUGIN_WINAPI
62 ".dll";
63#else
64 ".so";
65#endif
66
72 explicit DynamicLibrary(const std::string& filename, unsigned flags);
73
78
81
84
90
99 swap(to_move); // destructor of to_move will close current this library
100 return *this;
101 }
102
107 void swap(DynamicLibrary& to_swap) noexcept {
108 std::swap(handle, to_swap.handle);
109#ifdef PLASK__UTILS_PLUGIN_WINAPI
110 std::swap(unload, to_swap.unload);
111#endif
112 }
113
118
126 void open(const std::string& filename, unsigned flags);
127
131 void close();
132
140 void* getSymbol(const std::string &symbol_name) const;
141
150 template <typename SymbolType>
151 SymbolType getSymbol(const std::string &symbol_name) const {
152 return reinterpret_cast<SymbolType>(getSymbol(symbol_name));
153 }
154
156 void* operator[](const std::string &symbol_name) const {
157 return getSymbol(symbol_name);
158 }
159
167 void* requireSymbol(const std::string &symbol_name) const;
168
177 template <typename SymbolType>
178 SymbolType requireSymbol(const std::string &symbol_name) const {
179 return reinterpret_cast<SymbolType>(requireSymbol(symbol_name));
180 }
181
186 bool isOpen() const { return handle != 0; }
187
194 handle_t getSystemHandler() const { return handle; }
195
202 handle_t release();
203
207 bool operator<(const DynamicLibrary& other) const {
208#ifdef PLASK__UTILS_PLUGIN_WINAPI
209 return this->handle < other.handle || (this->handle == other.handle && !this->unload && other.unload);
210#else
211 return this->handle < other.handle;
212#endif
213 }
214
218 bool operator == (const DynamicLibrary& other) const {
219#ifdef PLASK__UTILS_PLUGIN_WINAPI
220 return (this->handle == other.handle) && (this->unload == other.unload);
221#else
222 return this->handle == other.handle;
223#endif
224 }
225
226};
227
228} // namespace plask
229
230namespace std {
231
233inline void swap(plask::DynamicLibrary& a, plask::DynamicLibrary& b) noexcept { a.swap(b); }
234
236template<>
237struct hash<plask::DynamicLibrary> {
238 std::hash<plask::DynamicLibrary::handle_t> h;
239public:
240 std::size_t operator()(const plask::DynamicLibrary &s) const {
241 return h(s.getSystemHandler());
242 }
243};
244
245
246
247}
248
249#endif // PLASK__UTILS_DYNLIB_LOADER_H