VLink 2.0.0
A high-performance communication middleware
Loading...
Searching...
No Matches
plugin.h File Reference

Type-safe dynamic plugin loader with version checking and lifecycle management. More...

#include <cstdint>
#include <deque>
#include <memory>
#include <string>
#include <string_view>
#include "./logger.h"
#include "./macros.h"
#include "./name_detector.h"
Include dependency graph for plugin.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

 Type-safe dynamic plugin loader with version verification and lifecycle management. More...

Namespaces

Macros

#define VLINK_PLUGIN_CREATE_FUNC_NAME   vlink_plugin_create
 Name of the plugin creation entry point exported by VLINK_PLUGIN_DECLARE.
#define VLINK_PLUGIN_DESTROY_FUNC_NAME   vlink_plugin_destroy
 Name of the plugin destruction entry point exported by VLINK_PLUGIN_DECLARE.
#define VLINK_PLUGIN_EXPORT   __attribute__((visibility("default")))
 Macro Definitions.
#define VLINK_PLUGIN_REGISTER(InterfaceType)
 Macro to register a plugin, automatically deriving its ID from the interface type name.
#define VLINK_PLUGIN_REGISTER_BY_ID(InterfaceType, PluginID)
 Macro to register a plugin with a specific, user-provided ID.
#define VLINK_PLUGIN_DECLARE(ImplementType, VersionMajor, VersionMinor)
 Declares a plugin creation and destruction interface.

Detailed Description

Type-safe dynamic plugin loader with version checking and lifecycle management.

Plugin wraps dlopen / LoadLibrary to load shared libraries that implement a given abstract C++ interface. Each plugin library must use the VLINK_PLUGIN_DECLARE macro to export vlink_plugin_create and vlink_plugin_destroy entry points.

Plugin ID: Every interface type T has a unique ID derived from its demangled type name (via NameDetector::get<T>()) or from a user-supplied literal (via VLINK_PLUGIN_REGISTER_BY_ID). The Plugin loader verifies that the ID embedded in the shared library matches the caller's expected interface type before returning a shared_ptr<T>.

Version checking: The caller specifies a required major/minor version. process_plugin_internal() performs the check inside the library's entry point and returns nullptr if the versions are incompatible, preventing ABI mismatches.

Lifecycle:

  • load<T>() opens the library, calls vlink_plugin_create, and wraps the result in a shared_ptr<T> with a custom deleter that calls vlink_plugin_destroy.
  • unload<T>() decrements the reference count; the library is closed when the count reaches zero.
  • clear() unloads all libraries.

Macros (defined in this header):

Macro Purpose
VLINK_PLUGIN_REGISTER In concrete class: derive plugin ID from type
VLINK_PLUGIN_REGISTER_BY_ID In concrete class: use a literal string as ID
VLINK_PLUGIN_DECLARE In .cpp: export create/destroy entry points
Example
// Interface header (my_plugin.h):
class MyPlugin {
public:
virtual ~MyPlugin() = default;
virtual void do_work() = 0;
};
// Implementation .cpp (my_plugin_impl.cpp):
class MyPluginImpl : public MyPlugin {
public:
void do_work() override { ... }
};
VLINK_PLUGIN_DECLARE(MyPluginImpl, 1, 0)
// Loader:
vlink::Plugin plugin;
auto impl = plugin.load<MyPlugin>("my_plugin_impl", 1, 0);
if (impl) {
impl->do_work();
}
#define VLINK_PLUGIN_DECLARE(ImplementType, VersionMajor, VersionMinor)
Declares a plugin creation and destruction interface.
Definition plugin.h:380
#define VLINK_PLUGIN_REGISTER(InterfaceType)
Macro to register a plugin, automatically deriving its ID from the interface type name.
Definition plugin.h:343

Macro Definition Documentation

◆ VLINK_PLUGIN_CREATE_FUNC_NAME

#define VLINK_PLUGIN_CREATE_FUNC_NAME   vlink_plugin_create

Name of the plugin creation entry point exported by VLINK_PLUGIN_DECLARE.

◆ VLINK_PLUGIN_DECLARE

#define VLINK_PLUGIN_DECLARE ( ImplementType,
VersionMajor,
VersionMinor )

Declares a plugin creation and destruction interface.

This macro declares the plugin entry points for creating and destroying the plugin interface. These functions are used by the Plugin class to load and unload the plugin.

Parameters
ImplementTypeThe concrete class implementing the plugin interface.
VersionMajorThe major version number of the plugin.
VersionMinorThe minor version number of the plugin.

◆ VLINK_PLUGIN_DESTROY_FUNC_NAME

#define VLINK_PLUGIN_DESTROY_FUNC_NAME   vlink_plugin_destroy

Name of the plugin destruction entry point exported by VLINK_PLUGIN_DECLARE.

◆ VLINK_PLUGIN_EXPORT

#define VLINK_PLUGIN_EXPORT   __attribute__((visibility("default")))

Macro Definitions.

◆ VLINK_PLUGIN_REGISTER

#define VLINK_PLUGIN_REGISTER ( InterfaceType)
Value:
public: \
static constexpr std::string_view get_plugin_id() { \
static_assert(std::is_abstract_v<InterfaceType>, "Plugin interface must be abstract class."); \
static_assert(std::has_virtual_destructor_v<InterfaceType>, "Plugin interface must have a virtual destructor."); \
}

Macro to register a plugin, automatically deriving its ID from the interface type name.

This macro should be used within the definition of a concrete plugin class. It defines a static constexpr member function get_plugin_id() that returns the name of the InterfaceType as the plugin's ID. It also includes a static assertion to ensure that the InterfaceType is an abstract class.

Parameters
InterfaceTypeThe abstract interface class that the plugin implements. The plugin ID will be derived from the name of this type.

◆ VLINK_PLUGIN_REGISTER_BY_ID

#define VLINK_PLUGIN_REGISTER_BY_ID ( InterfaceType,
PluginID )
Value:
public: \
static constexpr std::string_view get_plugin_id() { \
static_assert(std::is_abstract_v<InterfaceType>, "Plugin interface must be abstract class."); \
static_assert(std::has_virtual_destructor_v<InterfaceType>, "Plugin interface must have a virtual destructor."); \
return PluginID; \
}

Macro to register a plugin with a specific, user-provided ID.

This macro should be used within the definition of a concrete plugin class when you want to explicitly specify the plugin's ID, rather than deriving it from the interface type name. It defines a static constexpr member function get_plugin_id() that returns the provided PluginID. It also includes a static assertion to ensure that the InterfaceType is an abstract class.

Parameters
InterfaceTypeThe abstract interface class that the plugin implements.
PluginIDThe string literal to be used as the plugin's unique identifier.