@@ -76,11 +76,14 @@ namespace impl
7676typedef std::string LibraryPath;
7777typedef std::string ClassName;
7878typedef std::string BaseClassName;
79- typedef std::map<ClassName, impl:: AbstractMetaObjectBase * > FactoryMap;
79+ typedef std::map<ClassName, std::shared_ptr< AbstractMetaObjectBase> > FactoryMap;
8080typedef std::map<BaseClassName, FactoryMap> BaseToFactoryMapMap;
8181typedef std::pair<LibraryPath, std::shared_ptr<rcpputils::SharedLibrary>> LibraryPair;
8282typedef std::vector<LibraryPair> LibraryVector;
83- typedef std::vector<AbstractMetaObjectBase *> MetaObjectVector;
83+ typedef std::vector<std::shared_ptr<AbstractMetaObjectBase>> MetaObjectVector;
84+
85+ CLASS_LOADER_PUBLIC
86+ MetaObjectVector & getMetaObjectGraveyard ();
8487
8588CLASS_LOADER_PUBLIC
8689void printDebugInfoToScreen ();
@@ -139,8 +142,15 @@ ClassLoader * getCurrentlyActiveClassLoader();
139142 * @param loader - pointer to the currently active ClassLoader.
140143 */
141144CLASS_LOADER_PUBLIC
142- void setCurrentlyActiveClassLoader (ClassLoader * loader);
145+ void setCurrentlyActiveClassLoader (std::shared_ptr< ClassLoader> loader);
143146
147+ /* *
148+ * @brief Inserts meta object into the graveyard to preserve the lifetime.
149+ *
150+ * @param meta_obj - pointer to the meta object.
151+ */
152+ CLASS_LOADER_PUBLIC
153+ void insertMetaObjectIntoGraveyard (std::shared_ptr<AbstractMetaObjectBase> meta_obj);
144154
145155/* *
146156 * @brief This function extracts a reference to the FactoryMap for appropriate base class out of
@@ -240,8 +250,8 @@ void registerPlugin(const std::string & class_name, const std::string & base_cla
240250 }
241251
242252 // Create factory
243- impl::AbstractMetaObject<Base> * new_factory =
244- new impl::MetaObject<Derived, Base>(class_name, base_class_name);
253+ auto new_factory =
254+ std::make_shared< impl::MetaObject<Derived, Base> >(class_name, base_class_name);
245255 new_factory->addOwningClassLoader (getCurrentlyActiveClassLoader ());
246256 new_factory->setAssociatedLibraryPath (getCurrentlyLoadingLibraryName ());
247257
@@ -260,13 +270,17 @@ void registerPlugin(const std::string & class_name, const std::string & base_cla
260270 " and use either class_loader::ClassLoader/MultiLibraryClassLoader to open." ,
261271 class_name.c_str ());
262272 }
273+
274+ // We insert every factory into the graveyard to preserve the lifetime of all meta objects
275+ // until the process exits.
276+ insertMetaObjectIntoGraveyard (new_factory);
263277 factoryMap[class_name] = new_factory;
264278 getPluginBaseToFactoryMapMapMutex ().unlock ();
265279
266280 CONSOLE_BRIDGE_logDebug (
267281 " class_loader.impl: "
268282 " Registration of %s complete (Metaobject Address = %p)" ,
269- class_name.c_str (), reinterpret_cast <void *>(new_factory));
283+ class_name.c_str (), reinterpret_cast <void *>(new_factory. get () ));
270284}
271285
272286/* *
@@ -278,22 +292,22 @@ void registerPlugin(const std::string & class_name, const std::string & base_cla
278292 * @return A pointer to newly created plugin, note caller is responsible for object destruction
279293 */
280294template <typename Base>
281- Base * createInstance (const std::string & derived_class_name, ClassLoader * loader)
295+ Base * createInstance (const std::string & derived_class_name, std::shared_ptr< ClassLoader> loader)
282296{
283297 AbstractMetaObject<Base> * factory = nullptr ;
284298
285299 getPluginBaseToFactoryMapMapMutex ().lock ();
286300 FactoryMap & factoryMap = getFactoryMapForBaseClass<Base>();
287301 if (factoryMap.find (derived_class_name) != factoryMap.end ()) {
288- factory = dynamic_cast <impl::AbstractMetaObject<Base> *>(factoryMap[derived_class_name]);
302+ factory = dynamic_cast <impl::AbstractMetaObject<Base> *>(factoryMap[derived_class_name]. get () );
289303 } else {
290304 CONSOLE_BRIDGE_logError (
291305 " class_loader.impl: No metaobject exists for class type %s." , derived_class_name.c_str ());
292306 }
293307 getPluginBaseToFactoryMapMapMutex ().unlock ();
294308
295309 Base * obj = nullptr ;
296- if (factory != nullptr && factory->isOwnedBy (loader)) {
310+ if (factory != nullptr && factory->isOwnedBy (loader. get () )) {
297311 obj = factory->create ();
298312 }
299313
@@ -333,7 +347,7 @@ Base * createInstance(const std::string & derived_class_name, ClassLoader * load
333347 * @return A vector of strings where each string is a plugin we can create
334348 */
335349template <typename Base>
336- std::vector<std::string> getAvailableClasses (const ClassLoader * loader)
350+ std::vector<std::string> getAvailableClasses (std::shared_ptr< const ClassLoader> loader)
337351{
338352 std::lock_guard<std::recursive_mutex> lock (getPluginBaseToFactoryMapMapMutex ());
339353
@@ -342,8 +356,8 @@ std::vector<std::string> getAvailableClasses(const ClassLoader * loader)
342356 std::vector<std::string> classes_with_no_owner;
343357
344358 for (auto & it : factory_map) {
345- AbstractMetaObjectBase * factory = it.second ;
346- if (factory->isOwnedBy (loader)) {
359+ auto factory = it.second ;
360+ if (factory->isOwnedBy (loader. get () )) {
347361 classes.push_back (it.first );
348362 } else if (factory->isOwnedBy (nullptr )) {
349363 classes_with_no_owner.push_back (it.first );
@@ -364,7 +378,8 @@ std::vector<std::string> getAvailableClasses(const ClassLoader * loader)
364378 * within a ClassLoader's visible scope
365379 */
366380CLASS_LOADER_PUBLIC
367- std::vector<std::string> getAllLibrariesUsedByClassLoader (const ClassLoader * loader);
381+ std::vector<std::string> getAllLibrariesUsedByClassLoader (
382+ std::shared_ptr<const ClassLoader> loader);
368383
369384/* *
370385 * @brief Indicates if passed library loaded within scope of a ClassLoader.
@@ -375,7 +390,7 @@ std::vector<std::string> getAllLibrariesUsedByClassLoader(const ClassLoader * lo
375390 * @return true if the library is loaded within loader's scope, else false
376391 */
377392CLASS_LOADER_PUBLIC
378- bool isLibraryLoaded (const std::string & library_path, const ClassLoader * loader);
393+ bool isLibraryLoaded (const std::string & library_path, std::shared_ptr< const ClassLoader> loader);
379394
380395/* *
381396 * @brief Indicates if passed library has been loaded by ANY ClassLoader
0 commit comments