Defined in <plugin/PluginCatalog.hh> (CREATECATALOG) and <plugin/Plugin.hh> (CATALOG).
CREATECATALOG
#define CREATECATALOG( BASE ) \
template<> \
plugin::PluginCatalog< BASE >& plugin::Plugin< BASE >::catalog( ) \
{ \
static plugin::PluginCatalog< BASE > internalCatalog; \
return internalCatalog; \
}
Provides the definition of Plugin<BASE>::catalog() — an explicit specialisation returning a function-local static. Put it in exactly one translation unit, which the host links:
// Shape.cpp (host)
#include "Shape.hh"
#include <plugin/PluginCatalog.hh>
CREATECATALOG( Shape );
Why exactly one, in the host
- More than one definition → ODR violation / duplicate-symbol link error.
- In a plugin instead of the host → with
RTLD_GLOBALthe first DSO's catalog wins and things mostly work by luck; withRTLD_LOCALeach DSO gets its own catalog and the host sees no registrations. Put it in the host. - Missing entirely → link error: undefined reference to
plugin::Plugin<Shape>::catalog().
Because it is one function-local static reached through one specialisation, every REGISTER in every loaded DSO and every Shape::create call resolve to the same object (the loader uses RTLD_GLOBAL so the symbol is shared).
CATALOG
#define CATALOG( BASE ) plugin::Plugin< BASE >::catalog( )
A shorthand. CATALOG(Shape) ≡ plugin::Plugin<Shape>::catalog() ≡ Shape::catalog().
std::cout << CATALOG(Shape).size() << " shape plugins\n";
for( auto const& n : CATALOG(Shape).names(true) ) std::cout << " " << n << '\n';
Use whichever form reads best; they are identical.

