14#include <unordered_map>
18#define PLUGINS_EXTENSION ".dll"
22#define PLUGINS_EXTENSION ".dylib"
24#define PLUGINS_EXTENSION ".so"
58 other.handle =
nullptr;
75 explicit operator bool()
const {
return handle !=
nullptr; }
102 template <std::derived_from<IPlugin> T> std::shared_ptr<T>
loadPlugin(
const std::string &path)
104 std::scoped_lock lock(
m_mutex);
107 throw std::runtime_error(
"Plugin already loaded: " + path);
112 std::unique_ptr<IPlugin> plugin(entry());
114 throw std::runtime_error(
"EntryPoint failed: " + path);
116 T *typed =
dynamic_cast<T *
>(plugin.get());
118 throw std::runtime_error(
"Plugin type mismatch: " + path);
120 auto [it, inserted] =
m_plugins.emplace(path, std::move(plugin));
122 throw std::runtime_error(
"Failed to store plugin: " + path);
128 std::shared_ptr<IPlugin> baseShared(it->second.get(), [](
IPlugin *) {});
129 return std::shared_ptr<T>(baseShared, typed);
135 std::unordered_map<std::string, std::unique_ptr<IPlugin>>
m_plugins;
141 const LibHandle handle = LoadLibraryA(path.c_str());
144 throw std::runtime_error(
"Cannot load library: " + path);
148 const LibHandle handle = dlopen(path.c_str(), RTLD_LAZY);
151 const char *error = dlerror();
152 std::string msg =
"Cannot load library: " + path;
155 msg +=
" (" + std::string(error) +
")";
157 throw std::runtime_error(msg);
172 throw std::runtime_error(
"EntryPoint not found in plugin: " + path);
This file contains the plugin interface.
This file contains the Logger class.
static void log(const std::string &message, const LogLevel &logLevel)
Modern, type-safe plugin loader.
std::unordered_map< std::string, std::unique_ptr< IPlugin > > m_plugins
PluginLoader(PluginLoader &&)=delete
PluginLoader & operator=(PluginLoader &&)=delete
PluginLoader & operator=(const PluginLoader &)=delete
PluginLoader(const PluginLoader &)=delete
SharedLib loadLibrary(const std::string &path)
std::unordered_map< std::string, SharedLib > m_handles
EntryPointFn getEntryPoint(SharedLib &lib, const std::string &path)
std::shared_ptr< T > loadPlugin(const std::string &path)
Load a plugin of type T.
IPlugin *(*)() EntryPointFn
Handle to a dynamic library with RAII.
SharedLib & operator=(const SharedLib &)=delete
SharedLib(const LibHandle h=nullptr)
SharedLib & operator=(SharedLib &&other) noexcept
SharedLib(const SharedLib &)=delete
SharedLib(SharedLib &&other) noexcept