Python 3.3 has the PyMemoryView_FromMemory C-API function, which creates a Python memoryview object from the supplied C buffer. memoryview objects really implement a new-style buffer interface.
If you look at its sources , you will notice that they are quite simple. It does the same thing as PyMemoryView_FromBuffer , except the first one fills Py_buffer itself.
Since the latter exists in Python 2.7, why can't we just call PyBuffer_FillInfo ourselves?
from libc.stdlib cimport malloc from libc.string cimport memcpy cdef extern from "Python.h": ctypedef struct PyObject object PyMemoryView_FromBuffer(Py_buffer *view) int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int infoflags) enum: PyBUF_FULL_RO cdef void dummy_function(const void **p, size_t *l): cdef void *tmp = malloc(17) memcpy(tmp, "some test\0 bytes", 17) p[0] = tmp l[0] = 17 cpdef getbuf(): cdef const void *cstr cdef size_t l cdef Py_buffer buf_info cdef char[:] ret cdef int readonly dummy_function(&cstr, &l) readonly = 1 PyBuffer_FillInfo(&buf_info, NULL, <void*>cstr, l, readonly, PyBUF_FULL_RO) ret = PyMemoryView_FromBuffer(&buf_info) return ret
Note that, however, that the return value will have a view that looks like this: <MemoryView of 'memoryview' at 0x7f216fc70ad0> . This is because Cython seems to memoryview inside _memoryviewslice . Since memoryview objects already implement a buffer interface, perhaps you should just return the result of calling PyMemoryView_FromBuffer .
In addition, you are responsible for managing the lifetime of your buffer. memoryview objects created in this way will not automatically free memory. You must do this yourself, ensuring that you do this only after the memorybuffer refers to it. In this regard, Richard Hansen's answer is a much better alternative.
Wgh
source share