The example lives in example/plugin/ in the source tree. This page covers the host side: the extension point every plugin implements.
Build it with -DEXAMPLE=ON; the driver is testShape.
Shape.hh — the interface
// SPDX-License-Identifier: MIT
#pragma once
#include <ostream>
#include <plugin/Plugin.hh>
namespace plugin {
namespace example {
class Shape : public Plugin< Shape >
{
public:
Shape() = default;
virtual void setSize( unsigned int value ) = 0;
virtual unsigned int getSize() const = 0;
virtual void printOn( std::ostream& stream ) const = 0;
};
} // namespace example
} // namespace plugin
inline std::ostream& operator<<( std::ostream& stream, plugin::example::Shape& object )
{
object.printOn( stream );
return stream;
}
: public Plugin< Shape >— the CRTP hook.Shapenow has the staticcreate,loadandcatalogfromplugin::Plugin.- Three pure virtuals — the contract a plugin fills. Nothing else is exposed.
- Free
operator<<— plain C++, not part of the plugin machinery. It just forwards toprintOn, sostd::cout << *shapeworks in the driver.
This header is compiled into the host and into every plugin .so — it is the plugin SDK.
Shape.cpp — the catalog definition
// SPDX-License-Identifier: MIT
#include "Shape.hh"
#include <plugin/PluginCatalog.hh>
CREATECATALOG( plugin::example::Shape );
One line. CREATECATALOG expands to the definition of Plugin<Shape>::catalog() — a function returning a function-local static PluginCatalog<Shape>. It is here, in a .cpp the host links, and nowhere else:
- put it in two places → duplicate-symbol link error;
- put it in a plugin instead → the host links nothing that defines
catalog(), so it fails to link (or, if the plugin is also linked, the wrong catalog wins).
Because it is one static behind one symbol, and the loader uses RTLD_GLOBAL, every REGISTER in every loaded libShape*.so and every Shape::create in the host all touch the same map.
The CMake target
add_library( Shape SHARED Shape.cpp Shape.hh )
set_target_properties( Shape PROPERTIES
VERSION 1.0.0 SOVERSION 1 POSITION_INDEPENDENT_CODE ON )
Shape is SHARED, not MODULE — the plugins and the driver link against it. The plugins are MODULE (next page).
Next: Three plugins.

