2009-07-15 2 views
1

Я динамически загружаю библиотеку на C++, как описано here.Передача boost :: ptr_list из библиотеки клиенту

Мой абстрактный базовый класс выглядит следующим образом:

#include <boost/ptr_container/ptr_list.hpp> 
class Base { 
public: 
    virtual void get_list(boost::ptr_list<AnotherObject>& list) const = 0; 
}; 

И моя библиотека теперь обеспечивает производный класс Derived

class Derived : public Base { ... }; 

void Derived::get_list(boost::ptr_list<AnotherObject& list) const { 
    list.push_back(new AnotherObject(1)); 
    list.push_back(new AnotherObject(2)); 
} 

и create и destroy функции

extern "C" { 
    Base* create() { new Derived; } 
    destroy(Base* p) { delete p; } 
} 

Моя программа-клиент загружает библиотеку и два create и destroy функции. Затем он создает экземпляр Derived и использует его:

Base* obj = create(); 
boost::ptr_list<AnotherObject> list; 
obj->get_list(list); 

Теперь моя проблема: Когда список заполняется библиотека библиотеки new призвана создать AnotherObject с. С другой стороны, когда список уничтожается, клиентский delete вызывается для уничтожения AnotherObject. Что я могу сделать, чтобы избежать этой проблемы?

ответ

3
  1. Использовать std::list<shared_ptr<AnotherObject> >.
  2. Передайте пользовательский делектор в shared_ptr, который вызывает надлежащее удаление.
+0

Это часть системы плагинов. У каждой библиотеки есть, вероятно, ее собственное новое/удаление. Кроме того, я хочу собрать все мои объекты AnotherObjects в клиент-глобальный список.Таким образом, я также должен собрать все deleter ... – phlipsy

+0

Вам не нужно выполнять шаг 2. Просто используйте 'shared_ptr'.« Волшебно »знает, для чего« ​​delete' ». –

+0

Должно быть только одно deleter в exe, клиентские DLL не будут знать, как память удаляется. Идея состоит в том, чтобы создать все объекты внутри вашего основного exe и передать в качестве параметра shared_ptr deleter функцию, которая вызывает удаление из cpp lib exe. – rpg

0

Легкий ответ заключается в том, чтобы утверждать, что и приложение, и библиотека скомпилированы с той же версией компилятора, и в этом случае они оба получат одинаковые новые/удаленные версии.

+0

Я предполагаю, что он заменил операторы new/delete в основной программе, но библиотека их не получает. – AProgrammer

+0

Ну, он ничего не говорит, что сделал это. – 2009-07-15 12:45:47

+0

Это часть плагиновой системы. Таким образом, я должен как-то гарантировать, что он не сработает, если кто-то другой с другой стандартной библиотекой напишет новый плагин. – phlipsy

0

Лучший способ состоит в том, чтобы один оператор новый и один оператор удаляли для всей программы. Есть варианты связывания, которые могут помочь (я помню -Wl, - export-dynamic, но это может быть для другой, но связанной проблемы).

Если это невозможно, убедитесь, что все операции удаления выполняются тем же объектом, что и новый, поэтому не определяйте их в встроенных функциях.

Смежные вопросы