I first asked this in StackOverflow but didn’t get a satisfying answer, so I’ll give it a try here.
I have a dynamic array type in C++ that I would like to expose through the buffer protocol. The type is already exposed as a sequence in Python, but I want to build NumPy arrays with the C++ array data, and I am hoping that a buffer will be faster than the element-wise construction from a sequence.
Reading through the protocol description, I am not sure what is the correct way to do this. The problem is that, being a dynamic array, its memory may be rellocated, and the bounds of valid memory may change. But, from what I understand, the buffer protocol assumes that the exposed buffer will remain intact on the native side, at least as long as one Python buffer object is alive.
The only solution I can think of is copying the array contents into a new memory area when a buffer is requested and delete that memory after the buffer is no longer needed. But I am not sure if this complies with the buffer protocol, i.e. returning a buffer that may not represent the current state of the corresponding Python object.
The documentation on the obj
field of the Py_buffer
struct says:
As a special case, for temporary buffers that are wrapped by
PyMemoryView_FromBuffer()
orPyBuffer_FillInfo()
this field isNULL
. In general, exporting objects MUST NOT use this scheme.
If I did make a copy of the data on each buffer request, would it qualify as such a “temporary” buffer?
Obviously, making a copy of the data somewhat misses the point of the buffer protocol, but as I said I’m hoping NumPy array construction will be faster this way (that is, with just a memcpy
copy instead of a loop over sequence items).
EDIT: Just to be clear, this is not a Python type that is internally implemented with a C++ dynamic array. Rather, this is a C++ application which offers scripting through an embedded Python interpreter and that has a Python interface for its dynamic arrays. So I cannot just forbid modifications to the object while a buffer view is alive, because in general these dynamic arrays can be directly modified by C++ code (unless I make deeper changes to the dynamic array type, and not just its Python interface).