unsafe internal PyBuffer(PyObject exporter, PyBUF flags) { _view = new Py_buffer(); if (Runtime.PyObject_GetBuffer(exporter.Handle, ref _view, (int)flags) < 0) { throw PythonException.ThrowLastAsClrException(); } _exporter = exporter; var intPtrBuf = new IntPtr[_view.ndim]; if (_view.shape != IntPtr.Zero) { Marshal.Copy(_view.shape, intPtrBuf, 0, (int)_view.len * sizeof(IntPtr)); Shape = intPtrBuf.Select(x => (long)x).ToArray(); } if (_view.strides != IntPtr.Zero) { Marshal.Copy(_view.strides, intPtrBuf, 0, (int)_view.len * sizeof(IntPtr)); Strides = intPtrBuf.Select(x => (long)x).ToArray(); } if (_view.suboffsets != IntPtr.Zero) { Marshal.Copy(_view.suboffsets, intPtrBuf, 0, (int)_view.len * sizeof(IntPtr)); SubOffsets = intPtrBuf.Select(x => (long)x).ToArray(); } }
/// <summary> /// GetBuffer Method. This Method only works for objects that have a buffer (like "bytes", "bytearray" or "array.array") /// </summary> /// <remarks> /// Send a request to the PyObject to fill in view as specified by flags. If the PyObject cannot provide a buffer of the exact type, it MUST raise PyExc_BufferError, set view->obj to NULL and return -1. /// On success, fill in view, set view->obj to a new reference to exporter and return 0. In the case of chained buffer providers that redirect requests to a single object, view->obj MAY refer to this object instead of exporter(See Buffer Object Structures). /// Successful calls to <see cref="PyObject.GetBuffer"/> must be paired with calls to <see cref="PyBuffer.Dispose()"/>, similar to malloc() and free(). Thus, after the consumer is done with the buffer, <see cref="PyBuffer.Dispose()"/> must be called exactly once. /// </remarks> public PyBuffer GetBuffer(PyBUF flags = PyBUF.SIMPLE) { return(new PyBuffer(this, flags)); }