2011-11-13 5 views
7

J'essaie d'utiliser Boost.Python comme un wrapper pour une fonction C++ qui reçoit un pointeur, modifie les données (gérées sur le côté Python comme un tableau numpy par exemple) et retourne. Comment obtenir Python numpy et Boost.Python pour collaborer et pour me donner le pointeur brut à l'intérieur de la fonction?Comment passer un pointeur brut à 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 lorsque je tente,

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

Je reçois l'erreur,

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

Répondre

3

Une façon qui semble fonctionner, suggéré par Andreas Kloeckner, les commentaires et les alternatives sont les bienvenus. Le greet() est modifié comme suit,

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 il suffit d'utiliser:

print cmod.greet(a) 
0

Vous aurez probablement besoin d'utiliser l'interface numpy de ctypes pour obtenir un pointeur brut au stockage , puis faites un pointeur ctypes pour doubler pour passer dans l'appel. ndarray.data est un type de tampon, pas un pointeur.

Je n'ai aucune expérience avec boost.python, mais je soupçonne que quelque chose comme

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'> 

fonctionnera si elle est adoptée à une fonction enveloppé C++ attend un pointeur comme argument.

+0

Oui, j'ai essayé aussi. Le message d'erreur lit ensuite, Boost.Python.ArgumentError: les types d'arguments Python dans <...> .module.greet (LP_c_double) ne correspond pas à la signature C++: greet (double *) – rych

Questions connexes