Boost wrapper converting Boost::multi_array to PyArray
Hi. I am attempting to create a wrapper for a C++ method that returns a Boost::multi_array. I was hoping to convert this result to a PyArray without copying the underlying data. I have isolated my problem below, using a class with one method which creates a trivial multi_array, the converter code and the wrapper. I have included a very simple test.py file and its output. As the results show: 1. The results are correct for most elements of the array, but the first element of the array is getting overwritten. 2. Both the multi_array and the PyArray seem to have the correct value for the first element right before returning from the to_python_converter. So it seems like it must be happening either during or after the return. Can anyone shed any light on why this is happening? I am using a recent Enthought build of Python23 with mingw 3.2.3 compiler on a Windows XP machine. Thanks so much, Eli ///////////////////////File test.py import timeseries creator=timeseries.multi_array_creator() array=creator.getArray() print "\nIn Python array looks like: %s" % array /////////////////////// Output
execfile("test.py")
in C++: a[0][0] = 0 a[0][1] = 1 a[0][2] = 2 a[1][0] = 10 a[1][1] = 11 a[1][2] = 12 ... On entry to convert(), a[0][0] = 0 After PyArray creation a[0][0] = 0 Before return, PyArrayObject first slot = 0 In Python array looks like: array([[9623160, 1, 2], [10, 11, 12], [20, 21, 22]], 'i') //////////////////////// File multi_array_creator.hpp #include <iostream> #include "boost/multi_array.hpp" using namespace std; class multi_array_creator{ public: typedef boost::multi_array<int, 2> ArrayType; multi_array_creator(){ import_array() } ArrayType getArray(){ ArrayType* a=new ArrayType(boost::extents[3][3]); for (int i=0;i<3;i++){ for (int j=0;j<3;j++) (*a)[i][j] = 10*i+j; } cout << "in C++:" << endl; for (int i=0;i<2;i++) for (int j=0;j<3;j++) cout << "a[" << i << "][" << j << "] = " << (*a)[i][j] << " "; cout << " ... " << endl; return *a; } }; ///////////////////////// File multi_array_export.cpp #include <boost/python.hpp> #include <Numeric/arrayobject.h> #include <Python.h> #include <iostream> #include "multi_array_creator.hpp" using namespace std; using namespace boost; using namespace boost::python; struct MArrayToPYArray { static PyObject* convert(multi_array<int, 2> const& a) { cout << "On entry to convert(), a[0][0] = " << a[0][0] << endl; PyObject* po = PyArray_FromDimsAndData(2, (int*) a.shape(), PyArray_INT, (char*) (a.origin())); cout << "After PyArray creation a[0][0] = " << a[0][0] << endl; PyArrayObject* pao=(PyArrayObject*)po; cout <<"Before return, PyArrayObject first slot = " << *(int*)(pao->data)<< endl; return po; } }; void export_MultiArrayCreator(){ import_array(); class_<multi_array_creator>("multi_array_creator") .def("getArray", &multi_array_creator::getArray); to_python_converter<multi_array<int, 2>, MArrayToPYArray>(); } void export_MultiArrayCreator(); BOOST_PYTHON_MODULE(timeseries){ export_MultiArrayCreator(); }
participants (1)
-
Ateljevich, Eli