[C++-sig] Boost wrapper converting Boost::multi_array to PyArray

Ateljevich, Eli eli at water.ca.gov
Wed Jul 28 22:02:35 CEST 2004


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();

}

 

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20040728/37ac70c1/attachment.htm>


More information about the Cplusplus-sig mailing list