870 lines
64 KiB
HTML
870 lines
64 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<title>Buffer Protocol — Python 3.7.4 documentation</title>
|
||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||
|
||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||
|
||
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
||
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
title="Search within Python 3.7.4 documentation"
|
||
href="../_static/opensearch.xml"/>
|
||
<link rel="author" title="About these documents" href="../about.html" />
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||
<link rel="next" title="Old Buffer Protocol" href="objbuffer.html" />
|
||
<link rel="prev" title="Iterator Protocol" href="iter.html" />
|
||
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
|
||
<link rel="canonical" href="https://docs.python.org/3/c-api/buffer.html" />
|
||
|
||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||
<script type="text/javascript" src="../_static/switchers.js"></script>
|
||
|
||
|
||
|
||
<style>
|
||
@media only screen {
|
||
table.full-width-table {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
|
||
|
||
</head><body>
|
||
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="objbuffer.html" title="Old Buffer Protocol"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="iter.html" title="Iterator Protocol"
|
||
accesskey="P">previous</a> |</li>
|
||
<li><img src="../_static/py.png" alt=""
|
||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li>
|
||
<span class="language_switcher_placeholder">en</span>
|
||
<span class="version_switcher_placeholder">3.7.4</span>
|
||
<a href="../index.html">Documentation </a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >Python/C API Reference Manual</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="abstract.html" accesskey="U">Abstract Objects Layer</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" style="display: none" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" type="text" name="q" />
|
||
<input type="submit" value="Go" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<div class="section" id="buffer-protocol">
|
||
<span id="bufferobjects"></span><span id="index-0"></span><h1>Buffer Protocol<a class="headerlink" href="#buffer-protocol" title="Permalink to this headline">¶</a></h1>
|
||
<p>Certain objects available in Python wrap access to an underlying memory
|
||
array or <em>buffer</em>. Such objects include the built-in <a class="reference internal" href="../library/stdtypes.html#bytes" title="bytes"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytes</span></code></a> and
|
||
<a class="reference internal" href="../library/stdtypes.html#bytearray" title="bytearray"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytearray</span></code></a>, and some extension types like <a class="reference internal" href="../library/array.html#array.array" title="array.array"><code class="xref py py-class docutils literal notranslate"><span class="pre">array.array</span></code></a>.
|
||
Third-party libraries may define their own types for special purposes, such
|
||
as image processing or numeric analysis.</p>
|
||
<p>While each of these types have their own semantics, they share the common
|
||
characteristic of being backed by a possibly large memory buffer. It is
|
||
then desirable, in some situations, to access that buffer directly and
|
||
without intermediate copying.</p>
|
||
<p>Python provides such a facility at the C level in the form of the <a class="reference internal" href="#bufferobjects"><span class="std std-ref">buffer
|
||
protocol</span></a>. This protocol has two sides:</p>
|
||
<ul class="simple" id="index-1">
|
||
<li><p>on the producer side, a type can export a “buffer interface” which allows
|
||
objects of that type to expose information about their underlying buffer.
|
||
This interface is described in the section <a class="reference internal" href="typeobj.html#buffer-structs"><span class="std std-ref">Buffer Object Structures</span></a>;</p></li>
|
||
<li><p>on the consumer side, several means are available to obtain a pointer to
|
||
the raw underlying data of an object (for example a method parameter).</p></li>
|
||
</ul>
|
||
<p>Simple objects such as <a class="reference internal" href="../library/stdtypes.html#bytes" title="bytes"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytes</span></code></a> and <a class="reference internal" href="../library/stdtypes.html#bytearray" title="bytearray"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytearray</span></code></a> expose their
|
||
underlying buffer in byte-oriented form. Other forms are possible; for example,
|
||
the elements exposed by an <a class="reference internal" href="../library/array.html#array.array" title="array.array"><code class="xref py py-class docutils literal notranslate"><span class="pre">array.array</span></code></a> can be multi-byte values.</p>
|
||
<p>An example consumer of the buffer interface is the <a class="reference internal" href="../library/io.html#io.BufferedIOBase.write" title="io.BufferedIOBase.write"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write()</span></code></a>
|
||
method of file objects: any object that can export a series of bytes through
|
||
the buffer interface can be written to a file. While <code class="xref py py-meth docutils literal notranslate"><span class="pre">write()</span></code> only
|
||
needs read-only access to the internal contents of the object passed to it,
|
||
other methods such as <a class="reference internal" href="../library/io.html#io.BufferedIOBase.readinto" title="io.BufferedIOBase.readinto"><code class="xref py py-meth docutils literal notranslate"><span class="pre">readinto()</span></code></a> need write access
|
||
to the contents of their argument. The buffer interface allows objects to
|
||
selectively allow or reject exporting of read-write and read-only buffers.</p>
|
||
<p>There are two ways for a consumer of the buffer interface to acquire a buffer
|
||
over a target object:</p>
|
||
<ul class="simple">
|
||
<li><p>call <a class="reference internal" href="#c.PyObject_GetBuffer" title="PyObject_GetBuffer"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_GetBuffer()</span></code></a> with the right parameters;</p></li>
|
||
<li><p>call <a class="reference internal" href="arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a> (or one of its siblings) with one of the
|
||
<code class="docutils literal notranslate"><span class="pre">y*</span></code>, <code class="docutils literal notranslate"><span class="pre">w*</span></code> or <code class="docutils literal notranslate"><span class="pre">s*</span></code> <a class="reference internal" href="arg.html#arg-parsing"><span class="std std-ref">format codes</span></a>.</p></li>
|
||
</ul>
|
||
<p>In both cases, <a class="reference internal" href="#c.PyBuffer_Release" title="PyBuffer_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBuffer_Release()</span></code></a> must be called when the buffer
|
||
isn’t needed anymore. Failure to do so could lead to various issues such as
|
||
resource leaks.</p>
|
||
<div class="section" id="buffer-structure">
|
||
<span id="id1"></span><h2>Buffer structure<a class="headerlink" href="#buffer-structure" title="Permalink to this headline">¶</a></h2>
|
||
<p>Buffer structures (or simply “buffers”) are useful as a way to expose the
|
||
binary data from another object to the Python programmer. They can also be
|
||
used as a zero-copy slicing mechanism. Using their ability to reference a
|
||
block of memory, it is possible to expose any data to the Python programmer
|
||
quite easily. The memory could be a large, constant array in a C extension,
|
||
it could be a raw block of memory for manipulation before passing to an
|
||
operating system library, or it could be used to pass around structured data
|
||
in its native, in-memory format.</p>
|
||
<p>Contrary to most data types exposed by the Python interpreter, buffers
|
||
are not <a class="reference internal" href="structures.html#c.PyObject" title="PyObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject</span></code></a> pointers but rather simple C structures. This
|
||
allows them to be created and copied very simply. When a generic wrapper
|
||
around a buffer is needed, a <a class="reference internal" href="memoryview.html#memoryview-objects"><span class="std std-ref">memoryview</span></a> object
|
||
can be created.</p>
|
||
<p>For short instructions how to write an exporting object, see
|
||
<a class="reference internal" href="typeobj.html#buffer-structs"><span class="std std-ref">Buffer Object Structures</span></a>. For obtaining
|
||
a buffer, see <a class="reference internal" href="#c.PyObject_GetBuffer" title="PyObject_GetBuffer"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_GetBuffer()</span></code></a>.</p>
|
||
<dl class="type">
|
||
<dt id="c.Py_buffer">
|
||
<code class="descname">Py_buffer</code><a class="headerlink" href="#c.Py_buffer" title="Permalink to this definition">¶</a></dt>
|
||
<dd><dl class="member">
|
||
<dt id="c.Py_buffer.buf">
|
||
void *<code class="descname">buf</code><a class="headerlink" href="#c.Py_buffer.buf" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>A pointer to the start of the logical structure described by the buffer
|
||
fields. This can be any location within the underlying physical memory
|
||
block of the exporter. For example, with negative <a class="reference internal" href="#c.Py_buffer.strides" title="Py_buffer.strides"><code class="xref c c-member docutils literal notranslate"><span class="pre">strides</span></code></a>
|
||
the value may point to the end of the memory block.</p>
|
||
<p>For <a class="reference internal" href="../glossary.html#term-contiguous"><span class="xref std std-term">contiguous</span></a> arrays, the value points to the beginning of
|
||
the memory block.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="member">
|
||
<dt id="c.Py_buffer.obj">
|
||
void *<code class="descname">obj</code><a class="headerlink" href="#c.Py_buffer.obj" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>A new reference to the exporting object. The reference is owned by
|
||
the consumer and automatically decremented and set to <em>NULL</em> by
|
||
<a class="reference internal" href="#c.PyBuffer_Release" title="PyBuffer_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBuffer_Release()</span></code></a>. The field is the equivalent of the return
|
||
value of any standard C-API function.</p>
|
||
<p>As a special case, for <em>temporary</em> buffers that are wrapped by
|
||
<a class="reference internal" href="memoryview.html#c.PyMemoryView_FromBuffer" title="PyMemoryView_FromBuffer"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyMemoryView_FromBuffer()</span></code></a> or <a class="reference internal" href="#c.PyBuffer_FillInfo" title="PyBuffer_FillInfo"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBuffer_FillInfo()</span></code></a>
|
||
this field is <em>NULL</em>. In general, exporting objects MUST NOT
|
||
use this scheme.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="member">
|
||
<dt id="c.Py_buffer.len">
|
||
Py_ssize_t <code class="descname">len</code><a class="headerlink" href="#c.Py_buffer.len" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p><code class="docutils literal notranslate"><span class="pre">product(shape)</span> <span class="pre">*</span> <span class="pre">itemsize</span></code>. For contiguous arrays, this is the length
|
||
of the underlying memory block. For non-contiguous arrays, it is the length
|
||
that the logical structure would have if it were copied to a contiguous
|
||
representation.</p>
|
||
<p>Accessing <code class="docutils literal notranslate"><span class="pre">((char</span> <span class="pre">*)buf)[0]</span> <span class="pre">up</span> <span class="pre">to</span> <span class="pre">((char</span> <span class="pre">*)buf)[len-1]</span></code> is only valid
|
||
if the buffer has been obtained by a request that guarantees contiguity. In
|
||
most cases such a request will be <a class="reference internal" href="#c.PyBUF_SIMPLE" title="PyBUF_SIMPLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_SIMPLE</span></code></a> or <a class="reference internal" href="#c.PyBUF_WRITABLE" title="PyBUF_WRITABLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_WRITABLE</span></code></a>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="member">
|
||
<dt id="c.Py_buffer.readonly">
|
||
int <code class="descname">readonly</code><a class="headerlink" href="#c.Py_buffer.readonly" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>An indicator of whether the buffer is read-only. This field is controlled
|
||
by the <a class="reference internal" href="#c.PyBUF_WRITABLE" title="PyBUF_WRITABLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_WRITABLE</span></code></a> flag.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="member">
|
||
<dt id="c.Py_buffer.itemsize">
|
||
Py_ssize_t <code class="descname">itemsize</code><a class="headerlink" href="#c.Py_buffer.itemsize" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Item size in bytes of a single element. Same as the value of <a class="reference internal" href="../library/struct.html#struct.calcsize" title="struct.calcsize"><code class="xref py py-func docutils literal notranslate"><span class="pre">struct.calcsize()</span></code></a>
|
||
called on non-NULL <a class="reference internal" href="#c.Py_buffer.format" title="Py_buffer.format"><code class="xref c c-member docutils literal notranslate"><span class="pre">format</span></code></a> values.</p>
|
||
<p>Important exception: If a consumer requests a buffer without the
|
||
<a class="reference internal" href="#c.PyBUF_FORMAT" title="PyBUF_FORMAT"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_FORMAT</span></code></a> flag, <a class="reference internal" href="#c.Py_buffer.format" title="Py_buffer.format"><code class="xref c c-member docutils literal notranslate"><span class="pre">format</span></code></a> will
|
||
be set to <em>NULL</em>, but <a class="reference internal" href="#c.Py_buffer.itemsize" title="Py_buffer.itemsize"><code class="xref c c-member docutils literal notranslate"><span class="pre">itemsize</span></code></a> still has
|
||
the value for the original format.</p>
|
||
<p>If <a class="reference internal" href="#c.Py_buffer.shape" title="Py_buffer.shape"><code class="xref c c-member docutils literal notranslate"><span class="pre">shape</span></code></a> is present, the equality
|
||
<code class="docutils literal notranslate"><span class="pre">product(shape)</span> <span class="pre">*</span> <span class="pre">itemsize</span> <span class="pre">==</span> <span class="pre">len</span></code> still holds and the consumer
|
||
can use <a class="reference internal" href="#c.Py_buffer.itemsize" title="Py_buffer.itemsize"><code class="xref c c-member docutils literal notranslate"><span class="pre">itemsize</span></code></a> to navigate the buffer.</p>
|
||
<p>If <a class="reference internal" href="#c.Py_buffer.shape" title="Py_buffer.shape"><code class="xref c c-member docutils literal notranslate"><span class="pre">shape</span></code></a> is <em>NULL</em> as a result of a <a class="reference internal" href="#c.PyBUF_SIMPLE" title="PyBUF_SIMPLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_SIMPLE</span></code></a>
|
||
or a <a class="reference internal" href="#c.PyBUF_WRITABLE" title="PyBUF_WRITABLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_WRITABLE</span></code></a> request, the consumer must disregard
|
||
<a class="reference internal" href="#c.Py_buffer.itemsize" title="Py_buffer.itemsize"><code class="xref c c-member docutils literal notranslate"><span class="pre">itemsize</span></code></a> and assume <code class="docutils literal notranslate"><span class="pre">itemsize</span> <span class="pre">==</span> <span class="pre">1</span></code>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="member">
|
||
<dt id="c.Py_buffer.format">
|
||
const char *<code class="descname">format</code><a class="headerlink" href="#c.Py_buffer.format" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>A <em>NUL</em> terminated string in <a class="reference internal" href="../library/struct.html#module-struct" title="struct: Interpret bytes as packed binary data."><code class="xref py py-mod docutils literal notranslate"><span class="pre">struct</span></code></a> module style syntax describing
|
||
the contents of a single item. If this is <em>NULL</em>, <code class="docutils literal notranslate"><span class="pre">"B"</span></code> (unsigned bytes)
|
||
is assumed.</p>
|
||
<p>This field is controlled by the <a class="reference internal" href="#c.PyBUF_FORMAT" title="PyBUF_FORMAT"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_FORMAT</span></code></a> flag.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="member">
|
||
<dt id="c.Py_buffer.ndim">
|
||
int <code class="descname">ndim</code><a class="headerlink" href="#c.Py_buffer.ndim" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>The number of dimensions the memory represents as an n-dimensional array.
|
||
If it is <code class="docutils literal notranslate"><span class="pre">0</span></code>, <a class="reference internal" href="#c.Py_buffer.buf" title="Py_buffer.buf"><code class="xref c c-member docutils literal notranslate"><span class="pre">buf</span></code></a> points to a single item representing
|
||
a scalar. In this case, <a class="reference internal" href="#c.Py_buffer.shape" title="Py_buffer.shape"><code class="xref c c-member docutils literal notranslate"><span class="pre">shape</span></code></a>, <a class="reference internal" href="#c.Py_buffer.strides" title="Py_buffer.strides"><code class="xref c c-member docutils literal notranslate"><span class="pre">strides</span></code></a>
|
||
and <a class="reference internal" href="#c.Py_buffer.suboffsets" title="Py_buffer.suboffsets"><code class="xref c c-member docutils literal notranslate"><span class="pre">suboffsets</span></code></a> MUST be <em>NULL</em>.</p>
|
||
<p>The macro <code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_MAX_NDIM</span></code> limits the maximum number of dimensions
|
||
to 64. Exporters MUST respect this limit, consumers of multi-dimensional
|
||
buffers SHOULD be able to handle up to <code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_MAX_NDIM</span></code> dimensions.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="member">
|
||
<dt id="c.Py_buffer.shape">
|
||
Py_ssize_t *<code class="descname">shape</code><a class="headerlink" href="#c.Py_buffer.shape" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>An array of <code class="xref c c-type docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> of length <a class="reference internal" href="#c.Py_buffer.ndim" title="Py_buffer.ndim"><code class="xref c c-member docutils literal notranslate"><span class="pre">ndim</span></code></a>
|
||
indicating the shape of the memory as an n-dimensional array. Note that
|
||
<code class="docutils literal notranslate"><span class="pre">shape[0]</span> <span class="pre">*</span> <span class="pre">...</span> <span class="pre">*</span> <span class="pre">shape[ndim-1]</span> <span class="pre">*</span> <span class="pre">itemsize</span></code> MUST be equal to
|
||
<a class="reference internal" href="#c.Py_buffer.len" title="Py_buffer.len"><code class="xref c c-member docutils literal notranslate"><span class="pre">len</span></code></a>.</p>
|
||
<p>Shape values are restricted to <code class="docutils literal notranslate"><span class="pre">shape[n]</span> <span class="pre">>=</span> <span class="pre">0</span></code>. The case
|
||
<code class="docutils literal notranslate"><span class="pre">shape[n]</span> <span class="pre">==</span> <span class="pre">0</span></code> requires special attention. See <a class="reference internal" href="#complex-arrays">complex arrays</a>
|
||
for further information.</p>
|
||
<p>The shape array is read-only for the consumer.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="member">
|
||
<dt id="c.Py_buffer.strides">
|
||
Py_ssize_t *<code class="descname">strides</code><a class="headerlink" href="#c.Py_buffer.strides" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>An array of <code class="xref c c-type docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> of length <a class="reference internal" href="#c.Py_buffer.ndim" title="Py_buffer.ndim"><code class="xref c c-member docutils literal notranslate"><span class="pre">ndim</span></code></a>
|
||
giving the number of bytes to skip to get to a new element in each
|
||
dimension.</p>
|
||
<p>Stride values can be any integer. For regular arrays, strides are
|
||
usually positive, but a consumer MUST be able to handle the case
|
||
<code class="docutils literal notranslate"><span class="pre">strides[n]</span> <span class="pre"><=</span> <span class="pre">0</span></code>. See <a class="reference internal" href="#complex-arrays">complex arrays</a> for further information.</p>
|
||
<p>The strides array is read-only for the consumer.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="member">
|
||
<dt id="c.Py_buffer.suboffsets">
|
||
Py_ssize_t *<code class="descname">suboffsets</code><a class="headerlink" href="#c.Py_buffer.suboffsets" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>An array of <code class="xref c c-type docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> of length <a class="reference internal" href="#c.Py_buffer.ndim" title="Py_buffer.ndim"><code class="xref c c-member docutils literal notranslate"><span class="pre">ndim</span></code></a>.
|
||
If <code class="docutils literal notranslate"><span class="pre">suboffsets[n]</span> <span class="pre">>=</span> <span class="pre">0</span></code>, the values stored along the nth dimension are
|
||
pointers and the suboffset value dictates how many bytes to add to each
|
||
pointer after de-referencing. A suboffset value that is negative
|
||
indicates that no de-referencing should occur (striding in a contiguous
|
||
memory block).</p>
|
||
<p>If all suboffsets are negative (i.e. no de-referencing is needed), then
|
||
this field must be NULL (the default value).</p>
|
||
<p>This type of array representation is used by the Python Imaging Library
|
||
(PIL). See <a class="reference internal" href="#complex-arrays">complex arrays</a> for further information how to access elements
|
||
of such an array.</p>
|
||
<p>The suboffsets array is read-only for the consumer.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="member">
|
||
<dt id="c.Py_buffer.internal">
|
||
void *<code class="descname">internal</code><a class="headerlink" href="#c.Py_buffer.internal" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>This is for use internally by the exporting object. For example, this
|
||
might be re-cast as an integer by the exporter and used to store flags
|
||
about whether or not the shape, strides, and suboffsets arrays must be
|
||
freed when the buffer is released. The consumer MUST NOT alter this
|
||
value.</p>
|
||
</dd></dl>
|
||
|
||
</dd></dl>
|
||
|
||
</div>
|
||
<div class="section" id="buffer-request-types">
|
||
<span id="id2"></span><h2>Buffer request types<a class="headerlink" href="#buffer-request-types" title="Permalink to this headline">¶</a></h2>
|
||
<p>Buffers are usually obtained by sending a buffer request to an exporting
|
||
object via <a class="reference internal" href="#c.PyObject_GetBuffer" title="PyObject_GetBuffer"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_GetBuffer()</span></code></a>. Since the complexity of the logical
|
||
structure of the memory can vary drastically, the consumer uses the <em>flags</em>
|
||
argument to specify the exact buffer type it can handle.</p>
|
||
<p>All <a class="reference internal" href="#c.Py_buffer" title="Py_buffer"><code class="xref c c-data docutils literal notranslate"><span class="pre">Py_buffer</span></code></a> fields are unambiguously defined by the request
|
||
type.</p>
|
||
<div class="section" id="request-independent-fields">
|
||
<h3>request-independent fields<a class="headerlink" href="#request-independent-fields" title="Permalink to this headline">¶</a></h3>
|
||
<p>The following fields are not influenced by <em>flags</em> and must always be filled in
|
||
with the correct values: <a class="reference internal" href="#c.Py_buffer.obj" title="Py_buffer.obj"><code class="xref c c-member docutils literal notranslate"><span class="pre">obj</span></code></a>, <a class="reference internal" href="#c.Py_buffer.buf" title="Py_buffer.buf"><code class="xref c c-member docutils literal notranslate"><span class="pre">buf</span></code></a>,
|
||
<a class="reference internal" href="#c.Py_buffer.len" title="Py_buffer.len"><code class="xref c c-member docutils literal notranslate"><span class="pre">len</span></code></a>, <a class="reference internal" href="#c.Py_buffer.itemsize" title="Py_buffer.itemsize"><code class="xref c c-member docutils literal notranslate"><span class="pre">itemsize</span></code></a>, <a class="reference internal" href="#c.Py_buffer.ndim" title="Py_buffer.ndim"><code class="xref c c-member docutils literal notranslate"><span class="pre">ndim</span></code></a>.</p>
|
||
</div>
|
||
<div class="section" id="readonly-format">
|
||
<h3>readonly, format<a class="headerlink" href="#readonly-format" title="Permalink to this headline">¶</a></h3>
|
||
<blockquote>
|
||
<div><dl class="macro">
|
||
<dt id="c.PyBUF_WRITABLE">
|
||
<code class="descname">PyBUF_WRITABLE</code><a class="headerlink" href="#c.PyBUF_WRITABLE" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Controls the <a class="reference internal" href="#c.Py_buffer.readonly" title="Py_buffer.readonly"><code class="xref c c-member docutils literal notranslate"><span class="pre">readonly</span></code></a> field. If set, the exporter
|
||
MUST provide a writable buffer or else report failure. Otherwise, the
|
||
exporter MAY provide either a read-only or writable buffer, but the choice
|
||
MUST be consistent for all consumers.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="macro">
|
||
<dt id="c.PyBUF_FORMAT">
|
||
<code class="descname">PyBUF_FORMAT</code><a class="headerlink" href="#c.PyBUF_FORMAT" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Controls the <a class="reference internal" href="#c.Py_buffer.format" title="Py_buffer.format"><code class="xref c c-member docutils literal notranslate"><span class="pre">format</span></code></a> field. If set, this field MUST
|
||
be filled in correctly. Otherwise, this field MUST be <em>NULL</em>.</p>
|
||
</dd></dl>
|
||
|
||
</div></blockquote>
|
||
<p><a class="reference internal" href="#c.PyBUF_WRITABLE" title="PyBUF_WRITABLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_WRITABLE</span></code></a> can be |’d to any of the flags in the next section.
|
||
Since <a class="reference internal" href="#c.PyBUF_SIMPLE" title="PyBUF_SIMPLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_SIMPLE</span></code></a> is defined as 0, <a class="reference internal" href="#c.PyBUF_WRITABLE" title="PyBUF_WRITABLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_WRITABLE</span></code></a>
|
||
can be used as a stand-alone flag to request a simple writable buffer.</p>
|
||
<p><a class="reference internal" href="#c.PyBUF_FORMAT" title="PyBUF_FORMAT"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_FORMAT</span></code></a> can be |’d to any of the flags except <a class="reference internal" href="#c.PyBUF_SIMPLE" title="PyBUF_SIMPLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_SIMPLE</span></code></a>.
|
||
The latter already implies format <code class="docutils literal notranslate"><span class="pre">B</span></code> (unsigned bytes).</p>
|
||
</div>
|
||
<div class="section" id="shape-strides-suboffsets">
|
||
<h3>shape, strides, suboffsets<a class="headerlink" href="#shape-strides-suboffsets" title="Permalink to this headline">¶</a></h3>
|
||
<p>The flags that control the logical structure of the memory are listed
|
||
in decreasing order of complexity. Note that each flag contains all bits
|
||
of the flags below it.</p>
|
||
<table class="docutils align-center">
|
||
<colgroup>
|
||
<col style="width: 51%" />
|
||
<col style="width: 12%" />
|
||
<col style="width: 16%" />
|
||
<col style="width: 21%" />
|
||
</colgroup>
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Request</p></th>
|
||
<th class="head"><p>shape</p></th>
|
||
<th class="head"><p>strides</p></th>
|
||
<th class="head"><p>suboffsets</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><dl class="macro">
|
||
<dt id="c.PyBUF_INDIRECT">
|
||
<code class="descname">PyBUF_INDIRECT</code><a class="headerlink" href="#c.PyBUF_INDIRECT" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>if needed</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><dl class="macro">
|
||
<dt id="c.PyBUF_STRIDES">
|
||
<code class="descname">PyBUF_STRIDES</code><a class="headerlink" href="#c.PyBUF_STRIDES" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><dl class="macro">
|
||
<dt id="c.PyBUF_ND">
|
||
<code class="descname">PyBUF_ND</code><a class="headerlink" href="#c.PyBUF_ND" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>NULL</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><dl class="macro">
|
||
<dt id="c.PyBUF_SIMPLE">
|
||
<code class="descname">PyBUF_SIMPLE</code><a class="headerlink" href="#c.PyBUF_SIMPLE" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>NULL</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="section" id="contiguity-requests">
|
||
<span id="index-2"></span><h3>contiguity requests<a class="headerlink" href="#contiguity-requests" title="Permalink to this headline">¶</a></h3>
|
||
<p>C or Fortran <a class="reference internal" href="../glossary.html#term-contiguous"><span class="xref std std-term">contiguity</span></a> can be explicitly requested,
|
||
with and without stride information. Without stride information, the buffer
|
||
must be C-contiguous.</p>
|
||
<table class="docutils align-center">
|
||
<colgroup>
|
||
<col style="width: 49%" />
|
||
<col style="width: 10%" />
|
||
<col style="width: 13%" />
|
||
<col style="width: 17%" />
|
||
<col style="width: 11%" />
|
||
</colgroup>
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Request</p></th>
|
||
<th class="head"><p>shape</p></th>
|
||
<th class="head"><p>strides</p></th>
|
||
<th class="head"><p>suboffsets</p></th>
|
||
<th class="head"><p>contig</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><dl class="macro">
|
||
<dt id="c.PyBUF_C_CONTIGUOUS">
|
||
<code class="descname">PyBUF_C_CONTIGUOUS</code><a class="headerlink" href="#c.PyBUF_C_CONTIGUOUS" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>C</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><dl class="macro">
|
||
<dt id="c.PyBUF_F_CONTIGUOUS">
|
||
<code class="descname">PyBUF_F_CONTIGUOUS</code><a class="headerlink" href="#c.PyBUF_F_CONTIGUOUS" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>F</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><dl class="macro">
|
||
<dt id="c.PyBUF_ANY_CONTIGUOUS">
|
||
<code class="descname">PyBUF_ANY_CONTIGUOUS</code><a class="headerlink" href="#c.PyBUF_ANY_CONTIGUOUS" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>C or F</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><dl class="macro">
|
||
<dt>
|
||
<code class="descname">PyBUF_ND</code></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>C</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="section" id="compound-requests">
|
||
<h3>compound requests<a class="headerlink" href="#compound-requests" title="Permalink to this headline">¶</a></h3>
|
||
<p>All possible requests are fully defined by some combination of the flags in
|
||
the previous section. For convenience, the buffer protocol provides frequently
|
||
used combinations as single flags.</p>
|
||
<p>In the following table <em>U</em> stands for undefined contiguity. The consumer would
|
||
have to call <a class="reference internal" href="#c.PyBuffer_IsContiguous" title="PyBuffer_IsContiguous"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBuffer_IsContiguous()</span></code></a> to determine contiguity.</p>
|
||
<table class="docutils align-center">
|
||
<colgroup>
|
||
<col style="width: 36%" />
|
||
<col style="width: 8%" />
|
||
<col style="width: 11%" />
|
||
<col style="width: 14%" />
|
||
<col style="width: 9%" />
|
||
<col style="width: 12%" />
|
||
<col style="width: 9%" />
|
||
</colgroup>
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Request</p></th>
|
||
<th class="head"><p>shape</p></th>
|
||
<th class="head"><p>strides</p></th>
|
||
<th class="head"><p>suboffsets</p></th>
|
||
<th class="head"><p>contig</p></th>
|
||
<th class="head"><p>readonly</p></th>
|
||
<th class="head"><p>format</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><dl class="macro">
|
||
<dt id="c.PyBUF_FULL">
|
||
<code class="descname">PyBUF_FULL</code><a class="headerlink" href="#c.PyBUF_FULL" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>if needed</p></td>
|
||
<td><p>U</p></td>
|
||
<td><p>0</p></td>
|
||
<td><p>yes</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><dl class="macro">
|
||
<dt id="c.PyBUF_FULL_RO">
|
||
<code class="descname">PyBUF_FULL_RO</code><a class="headerlink" href="#c.PyBUF_FULL_RO" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>if needed</p></td>
|
||
<td><p>U</p></td>
|
||
<td><p>1 or 0</p></td>
|
||
<td><p>yes</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><dl class="macro">
|
||
<dt id="c.PyBUF_RECORDS">
|
||
<code class="descname">PyBUF_RECORDS</code><a class="headerlink" href="#c.PyBUF_RECORDS" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>U</p></td>
|
||
<td><p>0</p></td>
|
||
<td><p>yes</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><dl class="macro">
|
||
<dt id="c.PyBUF_RECORDS_RO">
|
||
<code class="descname">PyBUF_RECORDS_RO</code><a class="headerlink" href="#c.PyBUF_RECORDS_RO" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>U</p></td>
|
||
<td><p>1 or 0</p></td>
|
||
<td><p>yes</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><dl class="macro">
|
||
<dt id="c.PyBUF_STRIDED">
|
||
<code class="descname">PyBUF_STRIDED</code><a class="headerlink" href="#c.PyBUF_STRIDED" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>U</p></td>
|
||
<td><p>0</p></td>
|
||
<td><p>NULL</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><dl class="macro">
|
||
<dt id="c.PyBUF_STRIDED_RO">
|
||
<code class="descname">PyBUF_STRIDED_RO</code><a class="headerlink" href="#c.PyBUF_STRIDED_RO" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>U</p></td>
|
||
<td><p>1 or 0</p></td>
|
||
<td><p>NULL</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><dl class="macro">
|
||
<dt id="c.PyBUF_CONTIG">
|
||
<code class="descname">PyBUF_CONTIG</code><a class="headerlink" href="#c.PyBUF_CONTIG" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>C</p></td>
|
||
<td><p>0</p></td>
|
||
<td><p>NULL</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><dl class="macro">
|
||
<dt id="c.PyBUF_CONTIG_RO">
|
||
<code class="descname">PyBUF_CONTIG_RO</code><a class="headerlink" href="#c.PyBUF_CONTIG_RO" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
</td>
|
||
<td><p>yes</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>NULL</p></td>
|
||
<td><p>C</p></td>
|
||
<td><p>1 or 0</p></td>
|
||
<td><p>NULL</p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="complex-arrays">
|
||
<h2>Complex arrays<a class="headerlink" href="#complex-arrays" title="Permalink to this headline">¶</a></h2>
|
||
<div class="section" id="numpy-style-shape-and-strides">
|
||
<h3>NumPy-style: shape and strides<a class="headerlink" href="#numpy-style-shape-and-strides" title="Permalink to this headline">¶</a></h3>
|
||
<p>The logical structure of NumPy-style arrays is defined by <a class="reference internal" href="#c.Py_buffer.itemsize" title="Py_buffer.itemsize"><code class="xref c c-member docutils literal notranslate"><span class="pre">itemsize</span></code></a>,
|
||
<a class="reference internal" href="#c.Py_buffer.ndim" title="Py_buffer.ndim"><code class="xref c c-member docutils literal notranslate"><span class="pre">ndim</span></code></a>, <a class="reference internal" href="#c.Py_buffer.shape" title="Py_buffer.shape"><code class="xref c c-member docutils literal notranslate"><span class="pre">shape</span></code></a> and <a class="reference internal" href="#c.Py_buffer.strides" title="Py_buffer.strides"><code class="xref c c-member docutils literal notranslate"><span class="pre">strides</span></code></a>.</p>
|
||
<p>If <code class="docutils literal notranslate"><span class="pre">ndim</span> <span class="pre">==</span> <span class="pre">0</span></code>, the memory location pointed to by <a class="reference internal" href="#c.Py_buffer.buf" title="Py_buffer.buf"><code class="xref c c-member docutils literal notranslate"><span class="pre">buf</span></code></a> is
|
||
interpreted as a scalar of size <a class="reference internal" href="#c.Py_buffer.itemsize" title="Py_buffer.itemsize"><code class="xref c c-member docutils literal notranslate"><span class="pre">itemsize</span></code></a>. In that case,
|
||
both <a class="reference internal" href="#c.Py_buffer.shape" title="Py_buffer.shape"><code class="xref c c-member docutils literal notranslate"><span class="pre">shape</span></code></a> and <a class="reference internal" href="#c.Py_buffer.strides" title="Py_buffer.strides"><code class="xref c c-member docutils literal notranslate"><span class="pre">strides</span></code></a> are <em>NULL</em>.</p>
|
||
<p>If <a class="reference internal" href="#c.Py_buffer.strides" title="Py_buffer.strides"><code class="xref c c-member docutils literal notranslate"><span class="pre">strides</span></code></a> is <em>NULL</em>, the array is interpreted as
|
||
a standard n-dimensional C-array. Otherwise, the consumer must access an
|
||
n-dimensional array as follows:</p>
|
||
<blockquote>
|
||
<div><p><code class="docutils literal notranslate"><span class="pre">ptr</span> <span class="pre">=</span> <span class="pre">(char</span> <span class="pre">*)buf</span> <span class="pre">+</span> <span class="pre">indices[0]</span> <span class="pre">*</span> <span class="pre">strides[0]</span> <span class="pre">+</span> <span class="pre">...</span> <span class="pre">+</span> <span class="pre">indices[n-1]</span> <span class="pre">*</span> <span class="pre">strides[n-1]</span></code>
|
||
<code class="docutils literal notranslate"><span class="pre">item</span> <span class="pre">=</span> <span class="pre">*((typeof(item)</span> <span class="pre">*)ptr);</span></code></p>
|
||
</div></blockquote>
|
||
<p>As noted above, <a class="reference internal" href="#c.Py_buffer.buf" title="Py_buffer.buf"><code class="xref c c-member docutils literal notranslate"><span class="pre">buf</span></code></a> can point to any location within
|
||
the actual memory block. An exporter can check the validity of a buffer with
|
||
this function:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">verify_structure</span><span class="p">(</span><span class="n">memlen</span><span class="p">,</span> <span class="n">itemsize</span><span class="p">,</span> <span class="n">ndim</span><span class="p">,</span> <span class="n">shape</span><span class="p">,</span> <span class="n">strides</span><span class="p">,</span> <span class="n">offset</span><span class="p">):</span>
|
||
<span class="sd">"""Verify that the parameters represent a valid array within</span>
|
||
<span class="sd"> the bounds of the allocated memory:</span>
|
||
<span class="sd"> char *mem: start of the physical memory block</span>
|
||
<span class="sd"> memlen: length of the physical memory block</span>
|
||
<span class="sd"> offset: (char *)buf - mem</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">if</span> <span class="n">offset</span> <span class="o">%</span> <span class="n">itemsize</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="bp">False</span>
|
||
<span class="k">if</span> <span class="n">offset</span> <span class="o"><</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">offset</span><span class="o">+</span><span class="n">itemsize</span> <span class="o">></span> <span class="n">memlen</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="bp">False</span>
|
||
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">v</span> <span class="o">%</span> <span class="n">itemsize</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">strides</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="bp">False</span>
|
||
|
||
<span class="k">if</span> <span class="n">ndim</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="n">ndim</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">shape</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">strides</span>
|
||
<span class="k">if</span> <span class="mi">0</span> <span class="ow">in</span> <span class="n">shape</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="bp">True</span>
|
||
|
||
<span class="n">imin</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">strides</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">*</span><span class="p">(</span><span class="n">shape</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">ndim</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">strides</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="n">imax</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">strides</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">*</span><span class="p">(</span><span class="n">shape</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">ndim</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">strides</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span>
|
||
|
||
<span class="k">return</span> <span class="mi">0</span> <span class="o"><=</span> <span class="n">offset</span><span class="o">+</span><span class="n">imin</span> <span class="ow">and</span> <span class="n">offset</span><span class="o">+</span><span class="n">imax</span><span class="o">+</span><span class="n">itemsize</span> <span class="o"><=</span> <span class="n">memlen</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="pil-style-shape-strides-and-suboffsets">
|
||
<h3>PIL-style: shape, strides and suboffsets<a class="headerlink" href="#pil-style-shape-strides-and-suboffsets" title="Permalink to this headline">¶</a></h3>
|
||
<p>In addition to the regular items, PIL-style arrays can contain pointers
|
||
that must be followed in order to get to the next element in a dimension.
|
||
For example, the regular three-dimensional C-array <code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">v[2][2][3]</span></code> can
|
||
also be viewed as an array of 2 pointers to 2 two-dimensional arrays:
|
||
<code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">(*v[2])[2][3]</span></code>. In suboffsets representation, those two pointers
|
||
can be embedded at the start of <a class="reference internal" href="#c.Py_buffer.buf" title="Py_buffer.buf"><code class="xref c c-member docutils literal notranslate"><span class="pre">buf</span></code></a>, pointing
|
||
to two <code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">x[2][3]</span></code> arrays that can be located anywhere in memory.</p>
|
||
<p>Here is a function that returns a pointer to the element in an N-D array
|
||
pointed to by an N-dimensional index when there are both non-NULL strides
|
||
and suboffsets:</p>
|
||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span> <span class="o">*</span><span class="nf">get_item_pointer</span><span class="p">(</span><span class="kt">int</span> <span class="n">ndim</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">buf</span><span class="p">,</span> <span class="n">Py_ssize_t</span> <span class="o">*</span><span class="n">strides</span><span class="p">,</span>
|
||
<span class="n">Py_ssize_t</span> <span class="o">*</span><span class="n">suboffsets</span><span class="p">,</span> <span class="n">Py_ssize_t</span> <span class="o">*</span><span class="n">indices</span><span class="p">)</span> <span class="p">{</span>
|
||
<span class="kt">char</span> <span class="o">*</span><span class="n">pointer</span> <span class="o">=</span> <span class="p">(</span><span class="kt">char</span><span class="o">*</span><span class="p">)</span><span class="n">buf</span><span class="p">;</span>
|
||
<span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
|
||
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">ndim</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
||
<span class="n">pointer</span> <span class="o">+=</span> <span class="n">strides</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">*</span> <span class="n">indices</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">suboffsets</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">>=</span><span class="mi">0</span> <span class="p">)</span> <span class="p">{</span>
|
||
<span class="n">pointer</span> <span class="o">=</span> <span class="o">*</span><span class="p">((</span><span class="kt">char</span><span class="o">**</span><span class="p">)</span><span class="n">pointer</span><span class="p">)</span> <span class="o">+</span> <span class="n">suboffsets</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
|
||
<span class="p">}</span>
|
||
<span class="p">}</span>
|
||
<span class="k">return</span> <span class="p">(</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="n">pointer</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="buffer-related-functions">
|
||
<h2>Buffer-related functions<a class="headerlink" href="#buffer-related-functions" title="Permalink to this headline">¶</a></h2>
|
||
<dl class="function">
|
||
<dt id="c.PyObject_CheckBuffer">
|
||
int <code class="descname">PyObject_CheckBuffer</code><span class="sig-paren">(</span><a class="reference internal" href="structures.html#c.PyObject" title="PyObject">PyObject</a><em> *obj</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyObject_CheckBuffer" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Return <code class="docutils literal notranslate"><span class="pre">1</span></code> if <em>obj</em> supports the buffer interface otherwise <code class="docutils literal notranslate"><span class="pre">0</span></code>. When <code class="docutils literal notranslate"><span class="pre">1</span></code> is
|
||
returned, it doesn’t guarantee that <a class="reference internal" href="#c.PyObject_GetBuffer" title="PyObject_GetBuffer"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_GetBuffer()</span></code></a> will
|
||
succeed. This function always succeeds.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyObject_GetBuffer">
|
||
int <code class="descname">PyObject_GetBuffer</code><span class="sig-paren">(</span><a class="reference internal" href="structures.html#c.PyObject" title="PyObject">PyObject</a><em> *exporter</em>, <a class="reference internal" href="#c.Py_buffer" title="Py_buffer">Py_buffer</a><em> *view</em>, int<em> flags</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyObject_GetBuffer" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Send a request to <em>exporter</em> to fill in <em>view</em> as specified by <em>flags</em>.
|
||
If the exporter cannot provide a buffer of the exact type, it MUST raise
|
||
<code class="xref c c-data docutils literal notranslate"><span class="pre">PyExc_BufferError</span></code>, set <code class="xref c c-member docutils literal notranslate"><span class="pre">view->obj</span></code> to <em>NULL</em> and
|
||
return <code class="docutils literal notranslate"><span class="pre">-1</span></code>.</p>
|
||
<p>On success, fill in <em>view</em>, set <code class="xref c c-member docutils literal notranslate"><span class="pre">view->obj</span></code> to a new reference
|
||
to <em>exporter</em> and return 0. In the case of chained buffer providers
|
||
that redirect requests to a single object, <code class="xref c c-member docutils literal notranslate"><span class="pre">view->obj</span></code> MAY
|
||
refer to this object instead of <em>exporter</em> (See <a class="reference internal" href="typeobj.html#buffer-structs"><span class="std std-ref">Buffer Object Structures</span></a>).</p>
|
||
<p>Successful calls to <a class="reference internal" href="#c.PyObject_GetBuffer" title="PyObject_GetBuffer"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_GetBuffer()</span></code></a> must be paired with calls
|
||
to <a class="reference internal" href="#c.PyBuffer_Release" title="PyBuffer_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBuffer_Release()</span></code></a>, similar to <code class="xref c c-func docutils literal notranslate"><span class="pre">malloc()</span></code> and <code class="xref c c-func docutils literal notranslate"><span class="pre">free()</span></code>.
|
||
Thus, after the consumer is done with the buffer, <a class="reference internal" href="#c.PyBuffer_Release" title="PyBuffer_Release"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBuffer_Release()</span></code></a>
|
||
must be called exactly once.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyBuffer_Release">
|
||
void <code class="descname">PyBuffer_Release</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_buffer" title="Py_buffer">Py_buffer</a><em> *view</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyBuffer_Release" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Release the buffer <em>view</em> and decrement the reference count for
|
||
<code class="xref c c-member docutils literal notranslate"><span class="pre">view->obj</span></code>. This function MUST be called when the buffer
|
||
is no longer being used, otherwise reference leaks may occur.</p>
|
||
<p>It is an error to call this function on a buffer that was not obtained via
|
||
<a class="reference internal" href="#c.PyObject_GetBuffer" title="PyObject_GetBuffer"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_GetBuffer()</span></code></a>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyBuffer_SizeFromFormat">
|
||
Py_ssize_t <code class="descname">PyBuffer_SizeFromFormat</code><span class="sig-paren">(</span>const char<em> *</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyBuffer_SizeFromFormat" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Return the implied <a class="reference internal" href="#c.Py_buffer.itemsize" title="Py_buffer.itemsize"><code class="xref c c-data docutils literal notranslate"><span class="pre">itemsize</span></code></a> from <a class="reference internal" href="#c.Py_buffer.format" title="Py_buffer.format"><code class="xref c c-data docutils literal notranslate"><span class="pre">format</span></code></a>.
|
||
This function is not yet implemented.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyBuffer_IsContiguous">
|
||
int <code class="descname">PyBuffer_IsContiguous</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_buffer" title="Py_buffer">Py_buffer</a><em> *view</em>, char<em> order</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyBuffer_IsContiguous" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Return <code class="docutils literal notranslate"><span class="pre">1</span></code> if the memory defined by the <em>view</em> is C-style (<em>order</em> is
|
||
<code class="docutils literal notranslate"><span class="pre">'C'</span></code>) or Fortran-style (<em>order</em> is <code class="docutils literal notranslate"><span class="pre">'F'</span></code>) <a class="reference internal" href="../glossary.html#term-contiguous"><span class="xref std std-term">contiguous</span></a> or either one
|
||
(<em>order</em> is <code class="docutils literal notranslate"><span class="pre">'A'</span></code>). Return <code class="docutils literal notranslate"><span class="pre">0</span></code> otherwise. This function always succeeds.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyBuffer_ToContiguous">
|
||
int <code class="descname">PyBuffer_ToContiguous</code><span class="sig-paren">(</span>void<em> *buf</em>, <a class="reference internal" href="#c.Py_buffer" title="Py_buffer">Py_buffer</a><em> *src</em>, Py_ssize_t<em> len</em>, char<em> order</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyBuffer_ToContiguous" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Copy <em>len</em> bytes from <em>src</em> to its contiguous representation in <em>buf</em>.
|
||
<em>order</em> can be <code class="docutils literal notranslate"><span class="pre">'C'</span></code> or <code class="docutils literal notranslate"><span class="pre">'F'</span></code> (for C-style or Fortran-style ordering).
|
||
<code class="docutils literal notranslate"><span class="pre">0</span></code> is returned on success, <code class="docutils literal notranslate"><span class="pre">-1</span></code> on error.</p>
|
||
<p>This function fails if <em>len</em> != <em>src->len</em>.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyBuffer_FillContiguousStrides">
|
||
void <code class="descname">PyBuffer_FillContiguousStrides</code><span class="sig-paren">(</span>int<em> ndims</em>, Py_ssize_t<em> *shape</em>, Py_ssize_t<em> *strides</em>, int<em> itemsize</em>, char<em> order</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyBuffer_FillContiguousStrides" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Fill the <em>strides</em> array with byte-strides of a <a class="reference internal" href="../glossary.html#term-contiguous"><span class="xref std std-term">contiguous</span></a> (C-style if
|
||
<em>order</em> is <code class="docutils literal notranslate"><span class="pre">'C'</span></code> or Fortran-style if <em>order</em> is <code class="docutils literal notranslate"><span class="pre">'F'</span></code>) array of the
|
||
given shape with the given number of bytes per element.</p>
|
||
</dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="c.PyBuffer_FillInfo">
|
||
int <code class="descname">PyBuffer_FillInfo</code><span class="sig-paren">(</span><a class="reference internal" href="#c.Py_buffer" title="Py_buffer">Py_buffer</a><em> *view</em>, <a class="reference internal" href="structures.html#c.PyObject" title="PyObject">PyObject</a><em> *exporter</em>, void<em> *buf</em>, Py_ssize_t<em> len</em>, int<em> readonly</em>, int<em> flags</em><span class="sig-paren">)</span><a class="headerlink" href="#c.PyBuffer_FillInfo" title="Permalink to this definition">¶</a></dt>
|
||
<dd><p>Handle buffer requests for an exporter that wants to expose <em>buf</em> of size <em>len</em>
|
||
with writability set according to <em>readonly</em>. <em>buf</em> is interpreted as a sequence
|
||
of unsigned bytes.</p>
|
||
<p>The <em>flags</em> argument indicates the request type. This function always fills in
|
||
<em>view</em> as specified by flags, unless <em>buf</em> has been designated as read-only
|
||
and <a class="reference internal" href="#c.PyBUF_WRITABLE" title="PyBUF_WRITABLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">PyBUF_WRITABLE</span></code></a> is set in <em>flags</em>.</p>
|
||
<p>On success, set <code class="xref c c-member docutils literal notranslate"><span class="pre">view->obj</span></code> to a new reference to <em>exporter</em> and
|
||
return 0. Otherwise, raise <code class="xref c c-data docutils literal notranslate"><span class="pre">PyExc_BufferError</span></code>, set
|
||
<code class="xref c c-member docutils literal notranslate"><span class="pre">view->obj</span></code> to <em>NULL</em> and return <code class="docutils literal notranslate"><span class="pre">-1</span></code>;</p>
|
||
<p>If this function is used as part of a <a class="reference internal" href="typeobj.html#buffer-structs"><span class="std std-ref">getbufferproc</span></a>,
|
||
<em>exporter</em> MUST be set to the exporting object and <em>flags</em> must be passed
|
||
unmodified. Otherwise, <em>exporter</em> MUST be NULL.</p>
|
||
</dd></dl>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Buffer Protocol</a><ul>
|
||
<li><a class="reference internal" href="#buffer-structure">Buffer structure</a></li>
|
||
<li><a class="reference internal" href="#buffer-request-types">Buffer request types</a><ul>
|
||
<li><a class="reference internal" href="#request-independent-fields">request-independent fields</a></li>
|
||
<li><a class="reference internal" href="#readonly-format">readonly, format</a></li>
|
||
<li><a class="reference internal" href="#shape-strides-suboffsets">shape, strides, suboffsets</a></li>
|
||
<li><a class="reference internal" href="#contiguity-requests">contiguity requests</a></li>
|
||
<li><a class="reference internal" href="#compound-requests">compound requests</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#complex-arrays">Complex arrays</a><ul>
|
||
<li><a class="reference internal" href="#numpy-style-shape-and-strides">NumPy-style: shape and strides</a></li>
|
||
<li><a class="reference internal" href="#pil-style-shape-strides-and-suboffsets">PIL-style: shape, strides and suboffsets</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#buffer-related-functions">Buffer-related functions</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="iter.html"
|
||
title="previous chapter">Iterator Protocol</a></p>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="objbuffer.html"
|
||
title="next chapter">Old Buffer Protocol</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This Page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/3.7/Doc/c-api/buffer.rst"
|
||
rel="nofollow">Show Source
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
>index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="objbuffer.html" title="Old Buffer Protocol"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="iter.html" title="Iterator Protocol"
|
||
>previous</a> |</li>
|
||
<li><img src="../_static/py.png" alt=""
|
||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li>
|
||
<span class="language_switcher_placeholder">en</span>
|
||
<span class="version_switcher_placeholder">3.7.4</span>
|
||
<a href="../index.html">Documentation </a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >Python/C API Reference Manual</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="abstract.html" >Abstract Objects Layer</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" style="display: none" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" type="text" name="q" />
|
||
<input type="submit" value="Go" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="footer">
|
||
© <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
|
||
<br />
|
||
The Python Software Foundation is a non-profit corporation.
|
||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||
<br />
|
||
Last updated on Jul 13, 2019.
|
||
<a href="../bugs.html">Found a bug</a>?
|
||
<br />
|
||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.0.1.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |