2011-11-13 8 views
7

Estoy tratando de usar Boost.Python como un contenedor para una función de C++ que recibe un puntero, modifica los datos (administrados en el lado de Python como matriz numpy por ejemplo) y regresa. ¿Cómo hago para que Python numpy y Boost.Python colaboren y me den el puntero sin formato dentro de la función?Cómo pasar un puntero sin formato a Boost.Python?

#include <boost/python.hpp> 
namespace 
{ 
    char const *greet(double *p) 
    { 
    *p = 2.; 
    return "hello world"; 
    } 
} 
BOOST_PYTHON_MODULE(module) 
{ 
    boost::python::def("greet", &greet); 
} 

En Python cuando intento,

import numpy as np 
a = np.empty([2], dtype=np.double) 
raw_ptr = a.data 
print cmod.greet(raw_ptr) 

consigo el error,

Boost.Python.ArgumentError: Python argument types in 
<...>.module.greet(buffer) 
did not match C++ signature: 
greet(double*) 

Respuesta

3

Una forma en que parece funcionar, sugerida por Andreas Kloeckner, los comentarios y las alternativas son bienvenidos. El saludo() se modifica de la siguiente manera,

char const *greet(boost::python::object obj) { 
    PyObject* pobj = obj.ptr(); 
    Py_buffer pybuf; 
    if(PyObject_GetBuffer(pobj, &pybuf, PyBUF_SIMPLE)!=-1) 
    { 
     void *buf = pybuf.buf; 
     double *p = (double*)buf; 
     *p = 2.; 
     *(p+1) = 3; 
     PyBuffer_Release(&pybuf); 
    } 
    return "hello world"; 
    } 

en Python sólo tiene que utilizar:

print cmod.greet(a) 
0

Es probable que necesite utilizar la interfaz ctypes numpy para obtener un puntero prima para el almacenamiento , y luego hacer un puntero ctypes al doble para pasar a la llamada. ndarray.data es un tipo de memoria intermedia, no un puntero.

que no tienen ninguna experiencia con boost.python, pero sospecho algo así como

In [28]: x=np.array([1,2,3,4],dtype=np.double) 

In [29]: p=x.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) 

In [30]: type(p) 
Out[30]: <class 'ctypes.LP_c_double'> 

funcionará si pasa a una función envuelta C++ esperando un puntero como un argumento.

+0

Sí, lo he intentado también. El mensaje de error lee, Boost.Python.ArgumentError: tipos de argumentos Python en <...> .module.greet (LP_c_double) no coincide con la firma C++: greet (double *) – rych

Cuestiones relacionadas