Search code examples
pythonc++cpythonpybufferpep3118

Writing to new Python buffer interface


I have implemented the new python buffer interface in C++ outlined here:

https://docs.python.org/2/c-api/buffer.html

I have implemented my Py_buffer struct and filled it in:

template<typename T>
static int getbuffer(PyObject *obj, Py_buffer *view, int flags) 
{
    flags;
    static const Py_ssize_t suboffsets[1] = { 0};
    view->buf           = (void*)(_Cast<T>(obj)->getbuffer());
    view->obj           = NULL;
    view->len           = _Cast<T>(obj)->getbuffersize();
    view->itemsize      = 1;
    view->readonly      = _Cast<T>(obj)->getreadonly();
    view->ndim          = 0;
    view->format        = NULL;
    view->shape         = NULL;
    view->strides       = NULL;
    view->suboffsets    = NULL;
    view->internal      = NULL;
    return 0;
}

I am creating my Python buffer class in Python and handing it to C++. I am getting a pyObject along with my Py_Buffer. So now my question is, how am I supposed to write and resize this pyBuffer in C++? I can get access to the pointer directly and a size. But if its a newly created buffer how do I tell it how much space I need? There does not seem to be any sort of resize function for me to call.

I can use: int result = PyBuffer_FromContiguous(&m_view, const_cast<void*>(data), pySize, 'A');

to add data to my buffer. But my buffer must already have the correct size or it wont write. I do not think this is the correct way to be using it anyway.

Cython is not an option.


Solution

  • You shouldn't resize the Py_buffer directly, since it is just an interface to the data of a PyObject.

    Instead, use PyByteArray_Resize() (or possibly _PyString_Resize()) on the underlying PyObject.