Estoy usando Boost.Python para crear un contenedor para mi biblioteca C++, y estoy teniendo algunos problemas, buscando en Google todo el día no produjo ningún resultado. Por ejemplo, tengo el siguiente código:Boost.Python y C++ std :: vector de punteros
class Base
{
public:
virtual void func() = 0;
};
class Derived : public Base
{
public:
virtual void func()
{
cout << "Derived::func()"<< endl;
}
};
// wrapper for Base
struct BaseWrapper : Base, python::wrapper<Base>
{
virtual void func()
{
this->get_override("func");
}
};
Base* makeDerived()
{
return new Derived;
}
vector<Base*>* makeDerivedVec()
{
vector<Base*> *v = new vector<Base*>;
v->push_back(new Derived);
v->push_back(new Derived);
v->push_back(new Derived);
return v;
}
BOOST_PYTHON_MODULE(mylib)
{
// export Base
class_<BaseWrapper, noncopyable>("Base")
.def("func", pure_virtual(&Base::func));
class_<vector<Base*> >("BasePtrVec")
.def(vector_indexing_suite<vector<Base*> >());
// export Derived
class_<Derived, bases<Base> >("Derived")
.def("func", &Derived::func);
// export makeDerived()
def("makeDerived", &makeDerived, return_value_policy<manage_new_object>());
// export makeDerivedVec()
def("makeDerivedVec", &makeDerivedVec, return_value_policy<manage_new_object>());
}
Por lo tanto, compilarlo, la importación en Python y prueba esto:
b = mylib.Base() b.func()
d = mylib.makeDerived() d.func()
la primera línea, como se esperaba, se produce una excepción diciendo que b.func() es puro virtual, y la segunda línea imprime
Derivado :: func()
Y eso está bien.
Pero el código
dlist = mylib.makeDerivedVec()
for d in dlist:
d.func()
no funciona, y Python lanza una excepción:
TypeError: No to_python (by-value) converter found for C++ type: Base*
Por qué se maneja correctamente la Base * devuelto por makeDerived() y se niega a trabajar con la base * contenido en std :: vector? ¿Cómo puedo hacer que funcione?
Sí, haciendo que Base :: func() no puro resuelva el problema. Gracias, al menos por esta solución. Pero, ¿hay alguna solución alternativa que no cambie ninguna API existente? –
No solo se trata de que no sea puro lo que resuelve el problema, sino que también está registrando 'Base *' como un tipo de puntero a BaseWrapper, a menos que esté equivocado. Quizás haya una forma de forzar a impulsar python a aceptar un tipo con métodos virtuales puros como un tipo de puntero ... – James
Sí, me refería a hacer func() no puro y registrar Base * ptr resolvió el problema. ¿Puedes explicar mejor cómo puedo hacer que python acepte un tipo con virtuales puros? –