import ctypes from ctypes import (byref, POINTER, pythonapi, c_int, c_char, c_char_p, c_void_p, py_object, c_ssize_t) from .info import PY2 c_ssize_p = POINTER(c_ssize_t) PyObject_GetBuffer = pythonapi.PyObject_GetBuffer PyBuffer_Release = pythonapi.PyBuffer_Release PyBUF_SIMPLE = 0 PyBUF_WRITABLE = 1 class Py_buffer(ctypes.Structure): _fields_ = [ ("buf", c_void_p), ("obj", py_object), ("len", c_ssize_t), ("itemsize", c_ssize_t), ("readonly", c_int), ("ndim", c_int), ("format", c_char_p), ("shape", c_ssize_p), ("strides", c_ssize_p), ("suboffsets", c_ssize_p), ("internal", c_void_p) ] if PY2: _fields_.insert(-1, ("smalltable", c_ssize_t * 2)) @classmethod def get_from(cls, obj, flags=PyBUF_SIMPLE): buf = cls() PyObject_GetBuffer(py_object(obj), byref(buf), flags) return buf def release(self): PyBuffer_Release(byref(self)) def get_buffer(obj, writable=False): buf = Py_buffer.get_from(obj, PyBUF_WRITABLE if writable else PyBUF_SIMPLE) try: buffer_type = c_char * buf.len return buffer_type.from_address(buf.buf) finally: buf.release()