views:

1450

answers:

1

I am new to C++/Python mixed language programming and do not have much idea about Python/C API. I just started using Boost.Python to wrap a C++ library for Python. I am stuck at wrapping a function that takes pointer to an array as an argument. Following (2nd ctor) is its prototype in C++.

class AAF{
  AAF(AAF_TYPE t);
  AAF(double v0, const double * t1, const unsigned * t2, unsigned T);
  ~AAF();
}

Am I doing right by wrapping it like this in boost::python?

class_<AAF>("AAF", init<AAF_TYPE>())
  .def(init<double, const double*, const unsigned*, unsigned>());

Note that it compiled and linked successfully, but I couldn't figure out how to call it in Python. My naive tries like the following failed.

>>> z = AAF(10, [4, 5.5, 10], [1, 1, 2], 3);

Traceback (most recent call last):
  File "./test_interval.py", line 40, in <module>
    z = AAF(10, [4, 5.5, 10], [1, 1, 2], 3);
Boost.Python.ArgumentError: Python argument types in
    AAF.__init__(AAF, int, list, list, int)
did not match C++ signature:
    __init__(_object*, AAF_TYPE)
    __init__(_object*, double, double const*, unsigned int const*, unsigned int)

>>> t1 = array.array('d', [4, 5.5, 10])
>>> t2 = array.array('I', [1, 1, 2])
>>> z = AAF(10, t1, t2, 3);

Traceback (most recent call last):
  File "./test_interval.py", line 40, in <module>
    z = AAF(10, t1, t2, 3);
Boost.Python.ArgumentError: Python argument types in
    AAF.__init__(AAF, int, array.array, array.array, int)
did not match C++ signature:
    __init__(_object*, AAF_TYPE)
    __init__(_object*, double, double const*, unsigned int const*, unsigned int)

My second question is that do I also need to wrap the destructor? Please specify if this might be necessary in some cases but not always.

+1  A: 

The wrapping is right (in principle) but in

AAF(10, [4, 5.5, 10], [1, 1, 2], 3);

(as the interpreter points out) you're passing to your function python's list objects, not pointers.

In short, if your function needs only to work on python's lists you need to change your code to use that interface (instead of using pointers). If you need to keep that interface, you have to write a wrapper function that takes a list from python, does the proper conversion and calls your orginal c++ function. The same applies to numpy arrays.

Please note that boost::python offers some built-in mechanism to convert python containers to stl compatible containers.

An example wrapping code for your case could be

void f(list o) {
    std::size_t n = len(o);
    double* tmp = new double[n];
    for (int i = 0; i < n; i++) {
     tmp[i] = extract<double>(o[i]);
    }
    std::cout << std::endl;
    // use tmp
    delete tmp;
}

Please give a look at the boost.python tutorial at http://www.boost.org/doc/libs/1_39_0/libs/python/doc/tutorial/doc/html/index.html.

beb0s
Thanks for your reply, but as I said, I don't have much idea about Python/C API. Can you point somewhere so that I can find a way to convert Python lists to C++ array?
Aamir
I would say "to a C array" in this case, nevertheless I've added some example code.
beb0s