[C++-sig] Problem with using boost::python::object and PyArrayObject* and PyObject*

Qinfeng(Javen) Shi shiqinfeng at gmail.com
Mon Oct 16 14:40:34 CEST 2006


Dear All,

I used python object to implement something like function pointer in C.
So for my funcPtrTest3(boost::python::object), given a function object,
funcPtrTest3 will call object(a,b) inside. It works perfect when a, b are
simple python compatabile type(such as int, float).

It does't work when a, b are c array type, because python has no pointer. So
I use numpy.ndarray( PyArrayObject* in c) to wrap the c array. But python
reports a error that it seems python can't recognize PyArrayObject as
numpy.ndarray. If I use PyObject* instead of PyArrayObject*,it can't even be
compiled successfully.

Any help will be appreciated!

/-------------------------using PyArrayObject*
result------------------------------/
>>> import hello as H
>>> H.funcPtrTest3(H.norm2_distPyObject)
0.000000 1.000000 2.000000 3.000000 4.000000 Traceback (most recent call
last):
  File "<stdin>", line 1, in ?
TypeError: No to_python (by-value) converter found for C++ type:
PyArrayObject
>>>
/--------------------------c extension-----------------------/
void funcPtrTest3(boost::python::object arg_op)
{
    op = arg_op;
    float fArray[5] = {0,1,2,3,4};
    intp m = 5;
    PyArrayObject* c = convertPtrToPyArray(fArray,5);
    op(c,c,1000);
}

PyArrayObject* convertPtrToPyArray(float * p1,int point_len)
{
    for (int i = 0; i<point_len; i++)
        printf("%f ",p1[i]);
    intp m = point_len;
    PyObject* c1=PyArray_SimpleNew(1, &m, PyArray_FLOAT);
    void *arr_c1 = PyArray_DATA((PyArrayObject*)c1);
    memcpy(arr_c1, p1, PyArray_ITEMSIZE((PyArrayObject*) c1) * m);
    return (PyArrayObject*)c1;
 }

float norm2_distPyArrayObject(PyArrayObject* a, PyArrayObject* b,float
upper_bound)
{
  float* aPtr = (float*) PyArray_DATA(a);
  float* bPtr = (float*) PyArray_DATA(b);
  intp theSize=PyArray_Size((PyObject*)a);
  float sum = 0;
  for (int i=0;i<theSize;i++)  {
        float d1 = *(aPtr + i) - *(bPtr + i);
    d1 *= d1;
    sum = sum + d1;
    if (sum > upper_bound)
            return sqrt(sum);
  }
  return sqrt(sum);
}

BOOST_PYTHON_MODULE(hello)
{
    import_array();
    ar::array::set_module_and_type("numpy", "ndarray");
    def("funcPtrTest3", &funcPtrTest3);
    def("norm2_distPyArrayObject",&norm2_distPyArrayObject);
}

/---------------------using PyObject*
result--------------------------------/
/home/users/qshi/boost_1_33_1/boost/python/converter/arg_to_python.hpp: In
   static member function `static void
   boost::python::converter::detail::reject_raw_object_helper<T,
   Convertibility>::error(Convertibility) [with T = PyObject, Convertibility
=
   char*]'
/home/users/qshi/boost_1_33_1/boost/python/converter/arg_to_python.hpp:181:
error: incomplete
   type '
   boost::python::converter::detail::cannot_convert_raw_PyObject<PyObject*>'
   cannot be used to name a scope
/--------------------------------- c
extension-----------------------------------/
void funcPtrTest3(boost::python::object arg_op)
{
    op = arg_op;
    float fArray[5] = {0,1,2,3,4};
    intp m = 5;
    PyArrayObject* c = convertPtrToPyArray(fArray,5);
    op(c,c,1000);
}

PyObject* convertPtrToPyObject(float * p1, int point_len)
{
    for (int i = 0; i<point_len; i++)
        printf("%f ",p1[i]);
    intp m = point_len;
    PyObject* c1=PyArray_SimpleNew(1, &m, PyArray_FLOAT);
    void *arr_c1 = PyArray_DATA((PyArrayObject*)c1);
    memcpy(arr_c1, p1, PyArray_ITEMSIZE((PyArrayObject*) c1) * m);
    return c1;
}
float norm2_distPyObject(PyObject* a, PyObject* b)
{
  float* aPtr = (float*) PyArray_DATA((PyArrayObject*)a);
  float* bPtr = (float*) PyArray_DATA((PyArrayObject*)b);
  intp theSize=PyArray_Size(a);
  float sum = 0;
  for (int i=0;i<theSize;i++)  {
        float d1 = *(aPtr + i) - *(bPtr + i);
    d1 *= d1;
    sum = sum + d1;
  }
  return sqrt(sum);
}
BOOST_PYTHON_MODULE(hello)
{
    import_array();
    ar::array::set_module_and_type("numpy", "ndarray");
    def("funcPtrTest3", &funcPtrTest3);
    def("norm2_distPyObject",&norm2_distPyObject);
}


-- 
Qinfeng(Javen) Shi

Research School of Information Sciences and Engineering
Australian National University
Locked Bag 8001
Canberra ACT 2601
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20061016/f0c31763/attachment.htm>


More information about the Cplusplus-sig mailing list