Go to the documentation of this file.
32 #ifndef CLASS_LOADER__CLASS_LOADER_CORE_HPP_
33 #define CLASS_LOADER__CLASS_LOADER_CORE_HPP_
35 #include <boost/thread/recursive_mutex.hpp>
70 typedef std::map<ClassName, impl::AbstractMetaObjectBase *>
FactoryMap;
72 typedef std::pair<LibraryPath, Poco::SharedLibrary *>
LibraryPair;
137 template<
typename Base>
166 #if defined(__has_feature)
167 #if __has_feature(address_sanitizer) // for clang
168 #define __SANITIZE_ADDRESS__ // GCC already sets this
172 #if defined(__SANITIZE_ADDRESS__)
173 #include <sanitizer/lsan_interface.h>
184 template<
typename Derived,
typename Base>
185 void registerPlugin(
const std::string & class_name,
const std::string & base_class_name)
190 CONSOLE_BRIDGE_logDebug(
191 "class_loader.impl: "
192 "Registering plugin factory for class = %s, ClassLoader* = %p and library name %s.",
197 CONSOLE_BRIDGE_logDebug(
"%s",
198 "class_loader.impl: ALERT!!! "
199 "A library containing plugins has been opened through a means other than through the "
200 "class_loader or pluginlib package. "
201 "This can happen if you build plugin libraries that contain more than just plugins "
202 "(i.e. normal code your app links against). "
203 "This inherently will trigger a dlopen() prior to main() and cause problems as class_loader "
204 "is not aware of plugin factories that autoregister under the hood. "
205 "The class_loader package can compensate, but you may run into namespace collision problems "
206 "(e.g. if you have the same plugin class in two different libraries and you load them both "
207 "at the same time). "
208 "The biggest problem is that library can now no longer be safely unloaded as the "
209 "ClassLoader does not know when non-plugin code is still in use. "
210 "In fact, no ClassLoader instance in your application will be unable to unload any library "
211 "once a non-pure one has been opened. "
212 "Please refactor your code to isolate plugins into their own libraries.");
220 #if defined(__SANITIZE_ADDRESS__)
221 __lsan_ignore_object(new_factory);
230 FactoryMap & factoryMap = getFactoryMapForBaseClass<Base>();
231 if (factoryMap.find(class_name) != factoryMap.end()) {
232 CONSOLE_BRIDGE_logWarn(
233 "class_loader.impl: SEVERE WARNING!!! "
234 "A namespace collision has occurred with plugin factory for class %s. "
235 "New factory will OVERWRITE existing one. "
236 "This situation occurs when libraries containing plugins are directly linked against an "
237 "executable (the one running right now generating this message). "
238 "Please separate plugins out into their own library or just don't link against the library "
239 "and use either class_loader::ClassLoader/MultiLibraryClassLoader to open.",
242 factoryMap[class_name] = new_factory;
245 CONSOLE_BRIDGE_logDebug(
246 "class_loader.impl: "
247 "Registration of %s complete (Metaobject Address = %p)",
248 class_name.c_str(),
reinterpret_cast<void *
>(new_factory));
257 template<
typename Base>
263 FactoryMap & factoryMap = getFactoryMapForBaseClass<Base>();
264 if (factoryMap.find(derived_class_name) != factoryMap.end()) {
267 CONSOLE_BRIDGE_logError(
268 "class_loader.impl: No metaobject exists for class type %s.", derived_class_name.c_str());
272 Base * obj =
nullptr;
273 if (factory !=
nullptr && factory->
isOwnedBy(loader)) {
277 if (
nullptr == obj) {
278 if (factory && factory->
isOwnedBy(
nullptr)) {
279 CONSOLE_BRIDGE_logDebug(
"%s",
280 "class_loader.impl: ALERT!!! "
281 "A metaobject (i.e. factory) exists for desired class, but has no owner. "
282 "This implies that the library containing the class was dlopen()ed by means other than "
283 "through the class_loader interface. "
284 "This can happen if you build plugin libraries that contain more than just plugins "
285 "(i.e. normal code your app links against) -- that intrinsically will trigger a dlopen() "
287 "You should isolate your plugins into their own library, otherwise it will not be "
288 "possible to shutdown the library!");
293 "Could not create instance of type " + derived_class_name);
297 CONSOLE_BRIDGE_logDebug(
298 "class_loader.impl: Created instance of type %s and object pointer = %p",
299 (
typeid(obj).name()),
reinterpret_cast<void *
>(obj));
309 template<
typename Base>
314 FactoryMap & factory_map = getFactoryMapForBaseClass<Base>();
315 std::vector<std::string> classes;
316 std::vector<std::string> classes_with_no_owner;
318 for (
auto & it : factory_map) {
321 classes.push_back(it.first);
322 }
else if (factory->
isOwnedBy(
nullptr)) {
323 classes_with_no_owner.push_back(it.first);
329 classes.insert(classes.end(), classes_with_no_owner.begin(), classes_with_no_owner.end());
377 #endif // CLASS_LOADER__CLASS_LOADER_CORE_HPP_
CLASS_LOADER_PUBLIC 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 ...
std::pair< LibraryPath, Poco::SharedLibrary * > LibraryPair
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....
CLASS_LOADER_PUBLIC 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::vector< LibraryPair > LibraryVector
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...
CLASS_LOADER_PUBLIC 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
CLASS_LOADER_PUBLIC BaseToFactoryMapMap & getGlobalPluginBaseToFactoryMapMap()
Gets a handle to a global data structure that holds a map of base class names (Base class describes p...
CLASS_LOADER_PUBLIC boost::recursive_mutex & getPluginBaseToFactoryMapMapMutex()
CLASS_LOADER_PUBLIC bool hasANonPurePluginLibraryBeenOpened()
Indicates if a library containing more than just plugins has been opened by the running process.
CLASS_LOADER_PUBLIC bool isLibraryLoadedByAnybody(const std::string &library_path)
Indicates if passed library has been loaded by ANY ClassLoader.
std::vector< std::string > getAvailableClasses(ClassLoader *loader)
This function returns all the available class_loader in the plugin system that are derived from Base ...
std::string BaseClassName
CLASS_LOADER_PUBLIC ClassLoader * getCurrentlyActiveClassLoader()
Gets the ClassLoader currently in scope which used when a library is being loaded.
This class allows loading and unloading of dynamically linked libraries which contain class definitio...
CLASS_LOADER_PUBLIC 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...
CLASS_LOADER_PUBLIC boost::recursive_mutex & getLoadedLibraryVectorMutex()
To provide thread safety, all exposed plugin functions can only be run serially by multiple threads....
#define CLASS_LOADER_PUBLIC
CLASS_LOADER_PUBLIC bool isLibraryLoaded(const std::string &library_path, ClassLoader *loader)
Indicates if passed library loaded within scope of a ClassLoader. The library maybe loaded in memory,...
CLASS_LOADER_PUBLIC LibraryVector & getLoadedLibraryVector()
Gets a handle to a list of open libraries in the form of LibraryPairs which encode the library path+n...
std::map< BaseClassName, FactoryMap > BaseToFactoryMapMap
CLASS_LOADER_PUBLIC std::vector< std::string > getAllLibrariesUsedByClassLoader(const ClassLoader *loader)
This function returns the names of all libraries in use by a given class loader.
std::map< ClassName, impl::AbstractMetaObjectBase * > FactoryMap
CLASS_LOADER_PUBLIC 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.
CLASS_LOADER_PUBLIC void printDebugInfoToScreen()
CLASS_LOADER_PUBLIC void setCurrentlyActiveClassLoader(ClassLoader *loader)
Sets the ClassLoader currently in scope which used when a library is being loaded.
class_loader
Author(s): Mirza Shah, Steven! Ragnarök
autogenerated on Sun Apr 27 2025 03:01:10