2013-04-26 15 views
9

Ho una libreria C++ di terze parti in cui alcuni metodi di classe utilizzano buffer di byte non elaborati. Non sono abbastanza sicuro di come gestire Boost :: Python con esso.Come esporre i buffer di byte grezzi con Boost :: Python?

C++ intestazione biblioteca è qualcosa di simile:

class CSomeClass 
{ 
    public: 
     int load(unsigned char *& pInBufferData, int & iInBufferSize); 
     int save(unsigned char *& pOutBufferData, int & iOutBufferSize); 
} 

In bloccato con il boost :: codice Python ...

class_<CSomeClass>("CSomeClass", init<>()) 
    .def("load", &CSomeClass::load, (args(/* what do I put here??? */))) 
    .def("save", &CSomeClass::save, (args(/* what do I put here??? */))) 

Come posso avvolgere questi buffer prime per esporli come materie prime stringhe in Python?

risposta

8

si deve scrivere, te stesso, le funzioni del binding che restituirà un oggetto Py_buffer da tali dati, permettendo che il vostro a uno di sola lettura (utilizzare PyBuffer_FromMemory) o lettura-scrittura (usare PyBuffer_FromReadWriteMemory) il vostro pre-assegnati C/Memoria C++ da Python.

Si tratta di come sta andando a guardare come (feedback più benvenuto):

#include <boost/python.hpp> 

using namespace boost::python; 

//I'm assuming your buffer data is allocated from CSomeClass::load() 
//it should return the allocated size in the second argument 
static object csomeclass_load(CSomeClass& self) { 
    unsigned char* buffer; 
    int size; 
    self.load(buffer, size); 

    //now you wrap that as buffer 
    PyObject* py_buf = PyBuffer_FromReadWriteMemory(buffer, size); 
    object retval = object(handle<>(py_buf)); 
    return retval; 
} 

static int csomeclass_save(CSomeClass& self, object buffer) { 
    PyObject* py_buffer = buffer.ptr(); 
    if (!PyBuffer_Check(py_buffer)) { 
    //raise TypeError using standard boost::python mechanisms 
    } 

    //you can also write checks here for length, verify the 
    //buffer is memory-contiguous, etc. 
    unsigned char* cxx_buf = (unsigned char*)py_buffer.buf; 
    int size = (int)py_buffer.len; 
    return self.save(cxx_buf, size); 
} 

Più tardi, quando si associa CSomeClass, utilizzare le funzioni statiche sopra al posto dei metodi load e save:

//I think that you should use boost::python::arg instead of boost::python::args 
// -- it gives you better control on the documentation 
class_<CSomeClass>("CSomeClass", init<>()) 
    .def("load", &csomeclass_load, (arg("self")), "doc for load - returns a buffer") 
    .def("save", &csomeclass_save, (arg("self"), arg("buffer")), "doc for save - requires a buffer") 
    ; 

Questo mi sembrerebbe abbastanza pitone.

+1

'py_buffer' è di tipo' PyObject * 'e stai invocando' .buf' su di esso? –

+0

Penso che tu abbia ragione, ci dovrebbe essere un cast da qualche parte prima di 'PyBufferObject'. Questo codice ora sta diventando obsoleto. I buffer di nuovo stile sono presenti e probabilmente è consigliabile utilizzarli. –

+0

So che questa è una vecchia domanda, ma puoi pubblicare un link ad alcune informazioni su questi "buffer di nuovo stile"? Non riesco a trovare nulla:/ – jpihl

Problemi correlati