c++ - library - Uso de Boost Python y std:: shared_ptr
boost library c++ download (4)
Parece que boost :: python no es compatible con C ++ 11 std :: shared_ptr.
Si tiene un vistazo a file boost / python / converter / shared_ptr_to_python.hpp, encontrará la implementación de la función de plantilla shared_ptr_to_python (shared_ptr <T> const & x) para boost :: shared_ptr (explica por qué el código funciona bien para boost :: shared_ptr).
Creo que tienes varias opciones:
- usa boost :: shared_ptr (que intentas evitar)
- escriba su implementación de shared_ptr_to_python para std :: shared_ptr (en mi humilde opinión la mejor opción)
- enviar solicitud para impulsar :: desarrolladores de python para que sean compatibles con std :: shared_ptr
Intento que Boost Python juegue bien con std :: shared_ptr. Actualmente, estoy recibiendo este error:
Traceback (most recent call last):
File "test.py", line 13, in <module>
comp.place_annotation(circle.centre())
TypeError: No to_python (by-value) converter found for C++ type: std::shared_ptr<cgl::Anchor>
Desde llamar a circle.centre (), que devuelve un std :: shared_ptr. Podría cambiar cada std :: shared_ptr por boost :: shared_ptr (con lo que Boost Python juega muy bien) sin embargo, la cantidad de código para cambiar es bastante considerable y me gustaría usar la biblioteca estándar.
El método del círculo se declara así:
const std::shared_ptr<Anchor> centre() const
{
return Centre;
}
La clase de anclaje así:
class Anchor
{
Point Where;
Annotation* Parent;
public:
Anchor(Annotation* parent) :
Parent(parent)
{
// Do nothing.
}
void update(const Renderer& renderer)
{
if(Parent)
{
Parent->update(renderer);
}
}
void set(Point point)
{
Where = point;
}
Point where() const
{
return Where;
}
};
Y el código relevante de Boost Python es:
class_<Circle, bases<Annotation> >("Circle", init<float>())
.def("radius", &Circle::radius)
.def("set_radius", &Circle::set_radius)
.def("diameter", &Circle::diameter)
.def("top_left", &Circle::top_left)
.def("centre", &Circle::centre);
// The anchor base class.
class_<Anchor, boost::noncopyable>("Anchor", no_init)
.def("where", &Anchor::where);
Estoy usando Boost 1.48.0. ¿Algunas ideas?
Hay un informe de error para esto: https://svn.boost.org/trac/boost/ticket/6545
Parece que alguien está trabajando en eso.
Un fragmento de http://boost.2283326.n4.nabble.com/No-automatic-upcasting-with-std-shared-ptr-in-function-calls-td4573165.html :
/* make boost::python understand std::shared_ptr */
namespace boost {
template<typename T>
T *get_pointer(std::shared_ptr<T> p)
{
return p.get();
}
}
Trabajó para mi. Definirías tus clases como:
class_<foo, std::shared_ptr<foo>>("Foo", ...);
Con esto, otros métodos que devuelven std::shared_ptr<foo>
funcionarán.
Es posible que se requiera algo de magia para las funciones / polimorfismo virtuales, que deberían cubrirse en el hilo al que se vinculó.
A menos que haya entendido mal, creo que esto resuelve tu problema:
boost::python::register_ptr_to_python<std::shared_ptr<Anchor>>();
http://www.boost.org/doc/libs/1_57_0/libs/python/doc/v2/register_ptr_to_python.html