class_loader
master
The class_loader package is a ROS-independent package for loading plugins during runtime.
|
Go to the documentation of this file.
32 #ifndef CLASS_LOADER__CLASS_LOADER_CORE_HPP_
33 #define CLASS_LOADER__CLASS_LOADER_CORE_HPP_
48 # pragma clang diagnostic push
49 # pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
51 #include "console_bridge/console.h"
53 # pragma clang diagnostic pop
161 template<
typename Base>
209 template<
typename Derived,
typename Base>
215 CONSOLE_BRIDGE_logDebug(
216 "class_loader.impl: "
217 "Registering plugin factory for class = %s, ClassLoader* = %p and library name %s.",
222 CONSOLE_BRIDGE_logDebug(
224 "class_loader.impl: ALERT!!! "
225 "A library containing plugins has been opened through a means other than through the "
226 "class_loader or pluginlib package. "
227 "This can happen if you build plugin libraries that contain more than just plugins "
228 "(i.e. normal code your app links against). "
229 "This inherently will trigger a dlopen() prior to main() and cause problems as class_loader "
230 "is not aware of plugin factories that autoregister under the hood. "
231 "The class_loader package can compensate, but you may run into namespace collision problems "
232 "(e.g. if you have the same plugin class in two different libraries and you load them both "
233 "at the same time). "
234 "The biggest problem is that library can now no longer be safely unloaded as the "
235 "ClassLoader does not know when non-plugin code is still in use. "
236 "In fact, no ClassLoader instance in your application will be unable to unload any library "
237 "once a non-pure one has been opened. "
238 "Please refactor your code to isolate plugins into their own libraries.");
251 FactoryMap & factoryMap = getFactoryMapForBaseClass<Base>();
252 if (factoryMap.
find(class_name) != factoryMap.
end()) {
253 CONSOLE_BRIDGE_logWarn(
254 "class_loader.impl: SEVERE WARNING!!! "
255 "A namespace collision has occured with plugin factory for class %s. "
256 "New factory will OVERWRITE existing one. "
257 "This situation occurs when libraries containing plugins are directly linked against an "
258 "executable (the one running right now generating this message). "
259 "Please separate plugins out into their own library or just don't link against the library "
260 "and use either class_loader::ClassLoader/MultiLibraryClassLoader to open.",
263 factoryMap[class_name] = new_factory;
266 CONSOLE_BRIDGE_logDebug(
267 "class_loader.impl: "
268 "Registration of %s complete (Metaobject Address = %p)",
269 class_name.
c_str(),
reinterpret_cast<void *
>(new_factory));
280 template<
typename Base>
286 FactoryMap & factoryMap = getFactoryMapForBaseClass<Base>();
287 if (factoryMap.
find(derived_class_name) != factoryMap.
end()) {
290 CONSOLE_BRIDGE_logError(
291 "class_loader.impl: No metaobject exists for class type %s.", derived_class_name.
c_str());
295 Base * obj =
nullptr;
296 if (factory !=
nullptr && factory->
isOwnedBy(loader)) {
300 if (
nullptr == obj) {
301 if (factory && factory->
isOwnedBy(
nullptr)) {
302 CONSOLE_BRIDGE_logDebug(
304 "class_loader.impl: ALERT!!! "
305 "A metaobject (i.e. factory) exists for desired class, but has no owner. "
306 "This implies that the library containing the class was dlopen()ed by means other than "
307 "through the class_loader interface. "
308 "This can happen if you build plugin libraries that contain more than just plugins "
309 "(i.e. normal code your app links against) -- that intrinsically will trigger a dlopen() "
311 "You should isolate your plugins into their own library, otherwise it will not be "
312 "possible to shutdown the library!");
317 "Could not create instance of type " + derived_class_name);
321 CONSOLE_BRIDGE_logDebug(
322 "class_loader.impl: Created instance of type %s and object pointer = %p",
323 (
typeid(obj).name()), obj);
335 template<
typename Base>
340 FactoryMap & factory_map = getFactoryMapForBaseClass<Base>();
344 for (
auto & it : factory_map) {
348 }
else if (factory->
isOwnedBy(
nullptr)) {
349 classes_with_no_owner.
push_back(it.first);
355 classes.
insert(classes.
end(), classes_with_no_owner.
begin(), classes_with_no_owner.
end());
412 #endif // CLASS_LOADER__CLASS_LOADER_CORE_HPP_
std::recursive_mutex & getPluginBaseToFactoryMapMapMutex()
void loadLibrary(const std::string &library_path, ClassLoader *loader)
Loads a library into memory if it has not already been done so. Attempting to load an already loaded ...
bool isLibraryLoaded(const std::string &library_path, const ClassLoader *loader)
Indicates if passed library loaded within scope of a ClassLoader. The library maybe loaded in memory,...
void registerPlugin(const std::string &class_name, const std::string &base_class_name)
This function is called by the CLASS_LOADER_REGISTER_CLASS macro in plugin_register_macro....
Definition: class_loader_core.hpp:210
LibraryVector & getLoadedLibraryVector()
Gets a handle to a list of open libraries in the form of LibraryPairs which encode the library path+n...
Definition: class_loader.hpp:59
std::vector< LibraryPair > LibraryVector
Definition: class_loader_core.hpp:82
Base * createInstance(const std::string &derived_class_name, ClassLoader *loader)
This function creates an instance of a plugin class given the derived name of the class and returns a...
Definition: class_loader_core.hpp:281
std::vector< std::string > getAllLibrariesUsedByClassLoader(const ClassLoader *loader)
This function returns the names of all libraries in use by a given class loader.
std::string getCurrentlyLoadingLibraryName()
When a library is being loaded, in order for factories to know which library they are being associate...
std::vector< AbstractMetaObjectBase * > MetaObjectVector
Definition: class_loader_core.hpp:83
std::vector< std::string > getAvailableClasses(const ClassLoader *loader)
This function returns all the available class_loader in the plugin system that are derived from Base ...
Definition: class_loader_core.hpp:336
bool hasANonPurePluginLibraryBeenOpened()
Indicates if a library containing more than just plugins has been opened by the running process.
bool isLibraryLoadedByAnybody(const std::string &library_path)
Indicates if passed library has been loaded by ANY ClassLoader.
FactoryMap & getFactoryMapForBaseClass(const std::string &typeid_base_class_name)
This function extracts a reference to the FactoryMap for appropriate base class out of the global plu...
std::string BaseClassName
Definition: class_loader_core.hpp:78
ClassLoader * getCurrentlyActiveClassLoader()
Gets the ClassLoader currently in scope which used when a library is being loaded.
std::string LibraryPath
Definition: class_loader_core.hpp:76
This class allows loading and unloading of dynamically linked libraries which contain class definitio...
Definition: class_loader.hpp:79
void setCurrentlyLoadingLibraryName(const std::string &library_name)
When a library is being loaded, in order for factories to know which library they are being associate...
std::recursive_mutex & getLoadedLibraryVectorMutex()
To provide thread safety, all exposed plugin functions can only be run serially by multiple threads.
std::string ClassName
Definition: class_loader_core.hpp:77
#define CLASS_LOADER_PUBLIC
Definition: visibility_control.hpp:58
std::pair< LibraryPath, std::shared_ptr< rcpputils::SharedLibrary > > LibraryPair
Definition: class_loader_core.hpp:81
std::map< BaseClassName, FactoryMap > BaseToFactoryMapMap
Definition: class_loader_core.hpp:80
std::map< ClassName, impl::AbstractMetaObjectBase * > FactoryMap
Definition: class_loader_core.hpp:79
void unloadLibrary(const std::string &library_path, ClassLoader *loader)
Unloads a library if it loaded in memory and cleans up its corresponding class factories....
An exception class thrown when class_loader is unable to create a plugin.
Definition: exceptions.hpp:83
void printDebugInfoToScreen()
BaseToFactoryMapMap & getGlobalPluginBaseToFactoryMapMap()
Gets a handle to a global data structure that holds a map of base class names (Base class describes p...
void setCurrentlyActiveClassLoader(ClassLoader *loader)
Sets the ClassLoader currently in scope which used when a library is being loaded.