2013-04-26 96 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