Во-первых, убедитесь, что ваши классы действительно полиморфны (т. Е. Имеют хотя бы одну виртуальную функцию или виртуальный деструктор). Ваш пример выше не делает, хотя я уверен, что ваш реальный случай использования. Без этого не будет работать ни один из машин Boost.Python RTTI для полиморфизма.
Затем, если вы подвержены оба класса с Boost.Python и зарегистрированы shared_ptr
преобразователи для них:
#include <boost/python.hpp>
namespace bp = boost::python;
BOOST_PYTHON_MODULE(example) {
bp::class_<A >("A");
bp::register_ptr_to_python< boost::shared_ptr<A> >();
bp::class_< B, bp::bases<A> >("B");
bp::register_ptr_to_python< boost::shared_ptr<B> >();
}
... это все, что вам нужно сделать, чтобы убедиться, что Python только когда видит наиболее значимый производного типа. Нет необходимости делать что-либо особенное для обеспечения того, чтобы A
был сброшен до B
, когда это возможно.
Это все еще оставляет вопрос о том, как обернуть функцию, возвращающую контейнер. Самые простой, вероятно, использовать набор индексации включенный с Boost.Python:
http://www.boost.org/doc/libs/1_49_0/libs/python/doc/v2/indexing.html
Есть и другие варианты, плавающие вокруг сети (в том числе «версия 2» сюита индексации, которая лучше во многих отношениях, но не входит в Boost.Python), но для простых задач это, вероятно, наиболее удобно.
Действительно, виртуальный d'tor был тем, что у меня пропало. – shoosh
Что касается вопроса о том, как обернуть функцию, возвращающую контейнер: Этот метод также работает с использованием методов экспонирования, возвращающих boost :: python :: list. I.e. добавив boost :: shared_ptr в полиморфные элементы python в список. Разделение указателей при доступе к списку во время выполнения будет выполняться неявно, как описано (если указанные определения register_ptr_to_python <> существуют). – StefanQ