102#define VLINK_PLUGIN_CREATE_FUNC_NAME vlink_plugin_create
108#define VLINK_PLUGIN_DESTROY_FUNC_NAME vlink_plugin_destroy
185 [[nodiscard]] std::shared_ptr<T>
load(
186 const std::string& lib_name, uint16_t version_major, uint16_t version_minor,
const std::string& dir_name =
"",
203 bool unload(
const std::string& lib_name);
213 [[nodiscard]]
bool has_loaded(
const std::string& lib_name);
254 uint16_t local_version_major, uint16_t local_version_minor,
255 const std::string& target_plugin_id, uint16_t target_version_major,
256 uint16_t target_version_minor, uint8_t log_level);
259 Handle load_and_create(
const std::string& plugin_id,
const std::string& lib_name, uint16_t version_major,
260 uint16_t version_minor,
const std::string& dir_name,
261 const std::deque<std::string>& search_paths,
const std::string& function_name,
262 std::shared_ptr<PluginEntry>* plugin_entry);
264 bool unload(
const std::string& plugin_complex_id);
266 bool has_loaded(
const std::string& plugin_complex_id);
268 static bool destroy(std::shared_ptr<PluginEntry> plugin_entry,
Handle handle,
271 std::unique_ptr<struct PluginImpl> impl_;
281inline std::shared_ptr<T>
Plugin::load(
const std::string& lib_name, uint16_t version_major, uint16_t version_minor,
282 const std::string& dir_name,
const std::deque<std::string>& search_paths,
283 const std::string& function_name) {
284 static_assert(!T::get_plugin_id().empty(),
"Plugin id can not be empty.");
286 std::shared_ptr<PluginEntry> plugin_entry;
287 auto* handle = load_and_create(T::get_plugin_id().data(), lib_name, version_major, version_minor, dir_name,
288 search_paths, function_name, &plugin_entry);
294 return std::shared_ptr<T>(
static_cast<T*
>(handle), [plugin_entry = std::move(plugin_entry)](T* interface_ptr) {
295 destroy(std::move(plugin_entry), interface_ptr);
301 static_assert(!T::get_plugin_id().empty(),
"Plugin id can not be empty.");
308 static_assert(!T::get_plugin_id().empty(),
"Plugin id can not be empty.");
315 static_assert(!T::get_plugin_id().empty(),
"Plugin id can not be empty.");
317 return lib_name +
"@" + T::get_plugin_id().data();
326#if defined(_WIN32) || defined(__CYGWIN__)
327#define VLINK_PLUGIN_EXPORT __declspec(dllexport)
329#define VLINK_PLUGIN_EXPORT __attribute__((visibility("default")))
343#define VLINK_PLUGIN_REGISTER(InterfaceType) \
345 static constexpr std::string_view get_plugin_id() { \
346 static_assert(std::is_abstract_v<InterfaceType>, "Plugin interface must be abstract class."); \
347 static_assert(std::has_virtual_destructor_v<InterfaceType>, "Plugin interface must have a virtual destructor."); \
348 return vlink::NameDetector::get<InterfaceType>(); \
362#define VLINK_PLUGIN_REGISTER_BY_ID(InterfaceType, PluginID) \
364 static constexpr std::string_view get_plugin_id() { \
365 static_assert(std::is_abstract_v<InterfaceType>, "Plugin interface must be abstract class."); \
366 static_assert(std::has_virtual_destructor_v<InterfaceType>, "Plugin interface must have a virtual destructor."); \
380#define VLINK_PLUGIN_DECLARE(ImplementType, VersionMajor, VersionMinor) \
382 VLINK_PLUGIN_EXPORT void* VLINK_PLUGIN_CREATE_FUNC_NAME(const char* lib_name, const char* plugin_id, \
383 uint16_t version_major, uint16_t version_minor, \
384 uint8_t log_level) { \
385 static_assert(std::is_default_constructible_v<ImplementType>, \
386 "Plugin implementation must have default constructible"); \
387 static_assert(!ImplementType::get_plugin_id().empty(), "Plugin id can not be empty."); \
388 static_assert(!std::is_abstract_v<ImplementType>, "Plugin implementation cannot be an abstract class."); \
391 if VUNLIKELY (!vlink::Plugin::process_plugin_internal(lib_name, ImplementType::get_plugin_id().data(), \
392 VersionMajor, VersionMinor, plugin_id, version_major, \
393 version_minor, log_level)) { \
397 return new ImplementType; \
401 VLINK_PLUGIN_EXPORT bool VLINK_PLUGIN_DESTROY_FUNC_NAME(void* handle) { \
402 if VUNLIKELY (!handle) { \
407 delete static_cast<ImplementType*>(handle); \
Level
Severity level for log messages.
定义 logger.h:148
bool has_loaded(const std::string &lib_name)
Returns true if the plugin for interface T is currently loaded.
定义 plugin.h:307
static std::deque< std::string > default_search_path()
Returns the default search path list for finding plugin shared libraries.
bool unload(const std::string &lib_name)
Unloads the plugin library for interface T.
定义 plugin.h:300
void * Handle
Opaque handle to a loaded shared library object (used internally).
定义 plugin.h:127
static bool process_plugin_internal(const std::string &lib_name, const std::string &local_plugin_id, uint16_t local_version_major, uint16_t local_version_minor, const std::string &target_plugin_id, uint16_t target_version_major, uint16_t target_version_minor, uint8_t log_level)
Internal entry-point handler called from VLINK_PLUGIN_DECLARE.
std::string get_plugin_complex_id(const std::string &lib_name)
Returns the composite key used internally to identify a (library, interface) pair.
定义 plugin.h:314
void set_log_level(Logger::Level level)
Sets the log level used for plugin load/unload diagnostics.
~Plugin()
Destructor. Calls clear() to unload all still-loaded libraries.
Logger::Level get_log_level() const
Returns the current log level for plugin diagnostics.
std::shared_ptr< T > load(const std::string &lib_name, uint16_t version_major, uint16_t version_minor, const std::string &dir_name="", const std::deque< std::string > &search_paths=default_search_path(), const std::string &function_name=VLINK_MACRO_STRING_GET(VLINK_PLUGIN_CREATE_FUNC_NAME))
Loads a plugin implementing interface T from a shared library.
定义 plugin.h:281
Plugin()
Constructs a Plugin manager with an empty library registry.
void clear()
Unloads all loaded plugin libraries.
Global singleton logger with three output styles and pluggable backends.
Platform-independent macro definitions for the VLink library.
#define VUNLIKELY(...)
Shorthand alias for VLINK_UNLIKELY. Hints that the expression is unlikely true.
定义 macros.h:302
#define VLINK_EXPORT
定义 macros.h:85
#define VLINK_MACRO_STRING_GET(name)
Stringifies the expanded value of macro name (two-level expansion).
定义 macros.h:274
#define VLINK_DISALLOW_COPY_AND_ASSIGN(classname)
Deletes the copy constructor and copy-assignment operator of classname.
定义 macros.h:184
Compile-time type-name and enum-name detection utilities.
#define VLINK_PLUGIN_DESTROY_FUNC_NAME
Name of the plugin destruction entry point exported by VLINK_PLUGIN_DECLARE.
定义 plugin.h:108
#define VLINK_PLUGIN_CREATE_FUNC_NAME
Name of the plugin creation entry point exported by VLINK_PLUGIN_DECLARE.
定义 plugin.h:102