Corrade::PluginManager::AbstractPlugin class

Base class for plugin interfaces.

Makes it possible to connects every plugin instance to its corresponding plugin manager, which ensures the plugin can be unloaded only if there are no active instances. Besides that, provides access to interface-specific and plugin-specific metadata.

Subclassing

Plugin interface classes have to provide the following:

A minimal example is below. The pluginSearchPaths() function first lists a path relative to executable directory (which would be used for example when deploying a Windows build) and as a fallback a system location, depending on CMAKE_INSTALL_PREFIX that's propagated from CMake via a #define generated by configure_file(). The functions are inlined here, but it's advised to move their definitions to a separate source file.

class AbstractFilesystem: public PluginManager::AbstractPlugin {
    public:
        static Containers::StringView pluginInterface() {
            using namespace Containers::Literals;
            return "cz.mosra.corrade.AbstractFilesystem/1.0"_s;
        }

        static Containers::Array<Containers::String> pluginSearchPaths() {
            return {InPlaceInit, {
                "corrade/filesystems",
                Utility::Path::join(CMAKE_INSTALL_PREFIX, "lib/corrade/filesystems")
            }};
        }

        explicit AbstractFilesystem(PluginManager::AbstractManager& manager, const Containers::StringView& plugin):
            PluginManager::AbstractPlugin{manager, plugin} {}

        explicit AbstractFilesystem() = default;

        // the actual plugin interface goes here
};

See Plugin management for a detailed tutorial.

Derived classes

template<class Interface>
class AbstractManagingPlugin
Base class for plugin interfaces with access to associated manager.

Public static functions

static auto pluginInterface() -> Containers::StringView
Plugin interface string.
static auto pluginSearchPaths() -> Containers::Array<Containers::String>
Plugin search paths.
static auto pluginSuffix() -> Containers::StringView new in 2020.06
Plugin binary suffix.
static auto pluginMetadataSuffix() -> Containers::StringView new in 2020.06
Plugin metadata file suffix.
static void initialize()
Initialize plugin.
static void finalize()
Finalize plugin.

Constructors, destructors, conversion operators

AbstractPlugin() explicit
Default constructor.
AbstractPlugin(AbstractManager& manager, const Containers::StringView& plugin) explicit
Plugin manager constructor.
AbstractPlugin(const AbstractPlugin&) deleted
Copying is not allowed.
AbstractPlugin(AbstractPlugin&& other) noexcept
Move constructor.
~AbstractPlugin() pure virtual
Destructor.

Public functions

auto operator=(const AbstractPlugin&) -> AbstractPlugin& deleted
Copying is not allowed.
auto operator=(AbstractPlugin&&) -> AbstractPlugin& deleted
Only move construction is allowed.
auto canBeDeleted() -> bool virtual
Whether the plugin can be deleted.
auto plugin() const -> Containers::StringView
Plugin identifier string.
auto metadata() const -> const PluginMetadata*
Plugin metadata.
auto configuration() -> Utility::ConfigurationGroup&
Plugin-specific configuration.
auto configuration() const -> const Utility::ConfigurationGroup&

Function documentation

static Containers::StringView Corrade::PluginManager::AbstractPlugin::pluginInterface()

Plugin interface string.

Returns a string that is then expected to be matched by plugin implementations in the CORRADE_PLUGIN_REGISTER() macro call. Plugins that don't define the exact same interface string won't be loaded. This can be used to ensure the interface and plugin is correctly paired even in case where there is no ABI mismatch.

You should override this function in your plugin interface and return something meaningful. A good practice is to use a "Java package name"-style syntax, for example "cz.mosra.corrade.PluginManager.Test.AbstractFood/1.0". The interface name should also contain version identifier to make sure the plugin will not be loaded with incompatible interface version. The returned view is expected to be Containers::StringViewFlag::Global.

The default implementation returns an empty string, which is technically valid, but note that keeping it empty will inhibit various sanity checks when loading dynamic plugins, leading to crashes and security issues.

static Containers::Array<Containers::String> Corrade::PluginManager::AbstractPlugin::pluginSearchPaths()

Plugin search paths.

List of hardcoded absolute or relative paths where to search for plugins of given interface. Relative paths are relative to Utility::Path::executableLocation() directory. Earlier entries have more priority than later, search stops once a directory that exists is found. By default this function returns an empty list, you can use the convenience implicitPluginSearchPaths() helper for a consistent behavior on all platforms. If not using the helper, you're encouraged to use Containers::String::nullTerminatedGlobalView() to return string literals without unnecessary copies. See also Plugin directories for more information.

static Containers::StringView Corrade::PluginManager::AbstractPlugin::pluginSuffix() new in 2020.06

Plugin binary suffix.

Used for discovering plugins on the filesystem. By default set to platform's native extension for dynamic modules such as ".dll" or ".so", override this function in your plugin interface if you want a different suffix. The returned view is expected to be Containers::StringViewFlag::Global. With CMake you can override the suffix by setting the SUFFIX property, for example:

set_target_properties(MyPlugin PROPERTIES SUFFIX .mod)

static Containers::StringView Corrade::PluginManager::AbstractPlugin::pluginMetadataSuffix() new in 2020.06

Plugin metadata file suffix.

Suffix for plugin-specific metadata files. By default set to ".conf". If non-empty, the plugin manager will expect the files to exist on the filesystem when loading dynamic plugins, and static plugins have them bundled into the library. If empty, no plugin-specific metadata file will be loaded (and thus it's also not possible to specify inter-plugin dependencies and other properties). The returned view is expected to be Containers::StringViewFlag::Global. With CMake, the metadata file passed to corrade_add_plugin() or corrade_add_static_plugin() is expected to have the same extension or be set to "" when metadata are not used, for example:

corrade_add_plugin(MyPlugin
    ${MYPLUGINS_DEBUG_INSTALL_DIR}
    ${MYPLUGINS_RELEASE_INSTALL_DIR}
    MyPlugin.modconf # or "" when metadata not used
    MyPlugin.cpp)

static void Corrade::PluginManager::AbstractPlugin::initialize()

Initialize plugin.

You can override this function to perform initialization before any plugin instance is created. Default implementation does nothing.

If the plugin is static, this function is called on construction of corresponding plugin manager, if the plugin is dynamic, this function is called on plugin load. If the plugin is used directly without plugin manager, you have to call this function manually (if needed).

static void Corrade::PluginManager::AbstractPlugin::finalize()

Finalize plugin.

You can override this function to perform finalization after all plugin instances are destroyed. Default implementation does nothing.

If the plugin is static, this function is called on destruction of corresponding plugin manager, if the plugin is dynamic, this function is called on plugin unload. If the plugin is used directly without plugin manager, you have to call this function manually (if needed).

Corrade::PluginManager::AbstractPlugin::AbstractPlugin() explicit

Default constructor.

Define this constructor in your subclass only if you want to allow using the interface or plugin without plugin manager.

The metadata() function will return nullptr.

Corrade::PluginManager::AbstractPlugin::AbstractPlugin(AbstractManager& manager, const Containers::StringView& plugin) explicit

Plugin manager constructor.

Used by the plugin manager. Don't forget to redefine this constructor in all your subclasses.

The plugin parameter comes directly from Manager::instantiate() or Manager::loadAndInstantiate() — i.e., if a Containers::StringViewFlag::Global view got passed to these functions, it'll be global here as well.

Corrade::PluginManager::AbstractPlugin::AbstractPlugin(AbstractPlugin&& other) noexcept

Move constructor.

In order to avoid unnecessary allocations of internal state, the move is destructive, which means none of plugin(), metadata(), configuration() or AbstractManagingPlugin::manager() can be called on a moved-out instance.

Corrade::PluginManager::AbstractPlugin::~AbstractPlugin() pure virtual

Destructor.

If instantiated through plugin manager, unregisters this instance from it.

bool Corrade::PluginManager::AbstractPlugin::canBeDeleted() virtual

Whether the plugin can be deleted.

Called from PluginManager on all active instances before the plugin is unloaded. Returns true if it is safe to delete the instance from the manager, false if not. If any instance returns false, the plugin is not unloaded. See Plugin loading, instantiation and unloading for more information.

Containers::StringView Corrade::PluginManager::AbstractPlugin::plugin() const

Plugin identifier string.

Name under which the plugin was instantiated, either its true name or an alias. If the plugin was not instantiated via a plugin manager, returns an empty string. Use PluginMetadata::name() to get the plugin true name unconditionally.

The view points to memory owned by the plugin instance and is only guaranteed to stay valid until the instance gets destroyed.

Can't be called on a moved-out instance.

const PluginMetadata* Corrade::PluginManager::AbstractPlugin::metadata() const

Plugin metadata.

Metadata associated with given plugin. If the plugin was not instantiated through a plugin manager, returns nullptr.

Can't be called on a moved-out instance.

Utility::ConfigurationGroup& Corrade::PluginManager::AbstractPlugin::configuration()

Plugin-specific configuration.

Configuration associated with given plugin instance. Can be used to modify plugin behavior beyond what's possible through the plugin interface. Every instance gets a fresh copy from PluginMetadata::configuration(), modifications are affecting only particular plugin instance. If the plugin was not instantiated through a plugin manager or the [configuration] group was not present in the metadata, the returned group is empty.

Can't be called on a moved-out instance.

const Utility::ConfigurationGroup& Corrade::PluginManager::AbstractPlugin::configuration() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.