2013-04-26 12 views
9

Mam trzecią bibliotekę C++, w której niektóre metody klasy używają buforów surowych bajtów. Nie jestem do końca pewien, jak sobie z tym poradzić w Boost :: Pythonie.Jak naświetlić bufory bajtów surowych za pomocą Boost :: Python?

C++ nagłówek biblioteka jest coś takiego:

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

W zakleszczony z Boost :: kodzie Pythona ...

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

Jak mogę owinąć te surowe buforów wystawiać je jako surowy ciągi w Pythonie?

Odpowiedz

8

Trzeba pisać samemu, funkcje na oprawach, które zwróci Py_buffer obiekt z tych danych, pozwalając albo tylko do odczytu (użyj PyBuffer_FromMemory) lub odczytu (użyj PyBuffer_FromReadWriteMemory) swój wstępnie przyznane C/Pamięć C++ z Pythona.

Jak to będzie wyglądać (sprzężenie zwrotne najbardziej mile widziane):

#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); 
} 

później, gdy wiążą CSomeClass, użyj funkcji statycznych powyżej zamiast metod load i 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") 
    ; 

Wyglądałoby to dla mnie wystarczająco pytonowo.

+1

'py_buffer' jest typu' PyObject * 'i wywołujesz na nim' .buf'? –

+0

Myślę, że masz rację, gdzieś powinien być rzut od "PyBufferObject". Ten kod jest już przestarzały. Dostępne są bufory nowego stylu i prawdopodobnie należy rozważyć ich użycie. –

+0

Wiem, że to stare pytanie, ale czy możesz zamieścić link do niektórych informacji na temat tych "buforów w nowym stylu"? Nie mogę niczego znaleźć:/ – jpihl

Powiązane problemy