2013-04-26 98 views
9

我有第三方C++庫,其中一些類方法使用原始字節緩衝區。我不太清楚如何處理Boost :: Python。如何使用Boost :: Python公開原始字節緩衝區?

C++庫頭是一樣的東西:

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

在套牢了boost :: 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??? */))) 

如何包裝這些原始緩衝區它們暴露爲原料Python中的字符串?

回答

8

你必須寫,你自己,你的綁定功能,將來自數據返回Py_buffer對象,允許你要麼只讀(使用PyBuffer_FromMemory)或讀寫(使用PyBuffer_FromReadWriteMemory)的預分配C /來自Python的C++內存。

這是怎麼回事的樣子(反饋居多):

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

後來,當你綁定CSomeClass,使用上面的替代方法loadsave靜態功能:

//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") 
    ; 

這對我來說足夠pythonic。

+1

'py_buffer'的類型是'PyObject *',並且您正在調用'.buf'? – 2016-04-19 11:41:39

+0

我認爲你是對的,在'PyBufferObject'之前應該有一個位置。這段代碼現在已經過時了。新風格的緩衝區在那裏,可能應該考慮使用它們。 – 2016-04-20 10:20:01

+0

我知道這是一個古老的問題,但你可以發佈一個關於這些「新式緩衝區」的信息的鏈接?我似乎無法找到任何東西:/ – jpihl 2018-01-05 08:25:36