$darkmode
plugin.hpp File Reference
#include <type_traits>
Include dependency graph for plugin.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  cloe::PluginManifest
 

Macros

#define DLL_PUBLIC   __attribute__((visibility("default")))
 
#define CLOE_PLUGIN_MANIFEST_VERSION   1
 
#define CLOE_PLUGIN_GLIBC_DLOPEN_MODE   0
 
#define BASE_CLOE_FACTORY(xFactoryType)
 
#define EXPORT_CLOE_PLUGIN(xFactoryType)
 

Detailed Description

See also
cloe/version.hpp

This file enables controllers, simulators, and components to be easily used as plugins.

The library is never unloaded, so we can forget about the handle. It does mean that we leak it in the end though, so that might show up in valgrind or similar tools.

All controller plugins that we load should be compiled to the correct version. This is a precaution that will probably save us a lot of grief in the long run IF we keep bumping the versions found in <cloe/version.hpp>.

Debugging Plugins

If you run into any troubles when loading a plugin, make sure that the appropriate symbols are exported:

$ nm your_plugin.so | grep -e 'plugin_manifest|create_factory' 0000000000027949 T create_factory 000000000033ba30 D plugin_manifest

If that looks good, then possibly you need to recompile your plugin with the same version of Cloe that you are trying to load it with.

Macro Definition Documentation

◆ BASE_CLOE_FACTORY

#define BASE_CLOE_FACTORY (   xFactoryType)
Value:
std::conditional<std::is_base_of<::cloe::ControllerFactory, xFactoryType>::value, \
typename std::conditional< \
std::is_base_of<::cloe::SimulatorFactory, xFactoryType>::value, \
typename std::conditional< \
std::is_base_of<::cloe::ComponentFactory, xFactoryType>::value, \
::cloe::ComponentFactory, std::false_type>::type>::type>::type
Definition: component.hpp:210
Definition: controller.hpp:164
Definition: simulator.hpp:199

◆ EXPORT_CLOE_PLUGIN

#define EXPORT_CLOE_PLUGIN (   xFactoryType)
Value:
extern "C" DLL_PUBLIC const uint8_t cloe_plugin_manifest_version = CLOE_PLUGIN_MANIFEST_VERSION; \
extern "C" DLL_PUBLIC const ::cloe::PluginManifest cloe_plugin_manifest{ \
BASE_CLOE_FACTORY(xFactoryType)::PLUGIN_TYPE, \
BASE_CLOE_FACTORY(xFactoryType)::PLUGIN_API_VERSION, \
"cloe_plugin_create", \
CLOE_PLUGIN_GLIBC_DLOPEN_MODE, \
}; \
extern "C" DLL_PUBLIC ::cloe::ModelFactory* cloe_plugin_create() { return new xFactoryType{}; }

This macro makes the given factory available to Cloe as a plugin.

Example

Given your component binding FooBar with its factory FooBarFactory, you can, in your main source file, export it as a plugin for Cloe:

namespace foobar {

class FooBarFactory : public ControllerFactory {
  // ... implementation ...
};

} // namespace foobar

EXPORT_CLOE_PLUGIN(foobar::FooBarFactory)

The macro call should not be followed by a semicolon, it should appear in the global namespace, and it should only be called on classes that inherit from one of the supported plugin types: ControllerFactory, SimulatorFactory, and ComponentFactory. The macro argument should be a fully-qualified name of the factory.