The Gaudi Framework
v30r3 (a5ef0a68)
|
The Gaudi Plugin Service is a small tool to add to a C++ application the possibility of dynamically instantiate (via factories) objects from classes defined in plug-in (or component) libraries.
While being part of Gaudi, it only depends on a Posix system (support for other systems is possible, but very low priority).
To be able to use plug-ins from an application you need:
In the base class you should declare the signature of the the factory for your derived classes. For example, if your base class is called Foo
and you want to instantiate the derived classes with one std::string
argument, you can write something like:
The templated class Gaudi::PluginService::Factory
takes as template argument the ideal signature of the factory. The in the above example, the actual signature of the factory is std::unique_ptr<Foo>(const std::string&)
, but we declare is as returning Foo*
for brevity.
The plug-in class Bar
defined in the dynamically loaded library will require a declaration to the Plugin Service to use it, so in the source file you have to have something like:
The library with Foo
and the library with Bar
will have to be linked against the library libGaudiPluginService.so
.
To enable the automatic discovery of plugins, the library with Bar
must be processed by the program listcomponents
and the output must be stored in a file with extension .components
in a directory in the LD_LIBRARY_PATH
. For example, if the lib
directory contains libBar.so
and it is specified in the LD_LIBRARY_PATH
, you can call the commands:
Note that the .components
file does not need to be in the same directory as libBar.so
.
The application code, linked against the library providing Foo
can now instantiate objects of class Bar
like this:
where the first argument to the function create
is the name of the class you want to instantiate, and the other arguments are passed to the constructor of the class.
Together with the simple usage described above, the Gaudi Plugin Service allows you to use aliases to refer to the plug-in class. For example, for a templated plug-in class you may have:
but to instantiate it you must call
Which is error prone and unreadable, but you can declare the component class with and id (an alias):
(note that the id must support the <<
operator of std::ostream
). The call in the application becomes:
When dealing with components in namespaces, you have several ways to invoke DECLARE_COMPONENT
. For example, if you have the class Baz::Fun
you can declare it as a component class in any of the following ways:
In all cases the name of the factory to be passed to the create
function will be Baz::Fun
.
When using DECLARE_COMPONENT
, we register as factory for our class a function equivalent to
but it's possible to use custom factory functions. This is a rather convoluted example: