2011-01-27 17 views
7

¿Cómo paso una lista Python de mi tipo de objeto ClassName a una función C++ que acepta un vector<ClassName>?Pasar la lista de Python al vector C++ usando Boost.python

Lo mejor que encontré es algo como esto: example. Lamentablemente, el código falla y no puedo entender por qué. Esto es lo que solía:

template<typename T> 
void python_to_vector(boost::python::object o, vector<T>* v) { 
    try { 
     object iter_obj = object(handle<>(PyObject_GetIter(o.ptr()))); 
     return; 
     for (;;) { 
      object obj = extract<object>(iter_obj.attr("next")()); 
      // Should launch an exception if it cannot extract T 
      v->emplace_back(extract<T>(obj)); 
     } 
    } catch(error_already_set) { 
     PyErr_Clear(); 
     // If there is an exception (no iterator, extract failed or end of the 
     // list reached), clear it and exit the function 
     return; 
    } 
} 

Respuesta

10

Asumiendo que tiene función que toma un La forma más fácil std::vector<Foo>

void bar (std::vector<Foo> arg) 

a manejar esto es exponer el vector a python.

BOOST_PYTHON_MODULE(awesome_module) 
{ 
    class_<Foo>("Foo") 
     //methods and attrs here 
    ; 

    class_<std::vector<Foo> >("VectorOfFoo") 
     .def(vector_indexing_suite<std::vector<foo> >()) 
    ; 

    .def("bar", &bar) 
} 

Así que ahora en Python que puede pegarse Foo s en un vector y pasar el vector de bar

from awesome_module import * 
foo_vector = VectorOfFoo() 
foo_vector.extend(Foo(arg) for arg in arglist) 
bar(foo_vector) 
+0

Muchas gracias. ¿Hay alguna manera de hacer que la conversión de la lista al vector sea automática? –

+0

Lamentablemente, no. Sin embargo, puede tener una función escrita en el lado de python que tome una lista, la convierta en un vector y la pase a la función de barra. Eso ayudará a ocultar un poco la fealdad de C++. –

3

Encontró un iterador que resuelve mi problema:

#include <boost/python/stl_iterator.hpp> 
template<typename T> 
void python_to_vector(boost::python::object o, vector<T>* v) { 
    stl_input_iterator<T> begin(o); 
    stl_input_iterator<T> end; 
    v->clear(); 
    v->insert(v->end(), begin, end); 
} 
+0

Sería mucho más fácil de hacer este trabajo en el lado pitón. Simplemente envuelva el vector usando vector_indexing_suite, y agregue lo que necesite en python, antes de entregarlo a C++ –

+0

@Matthew: ¿Le importaría agregar una respuesta? No sé a qué te refieres. –

Cuestiones relacionadas