Fix undefined memoryview format (#2223)
* Fix undefined memoryview format
* Add missing <algorithm> header
* Add workaround for py27 array compatibility
* Workaround py27 memoryview behavior
* Fix memoryview constructor from buffer_info
* Workaround PyMemoryView_FromMemory availability in py27
* Fix up memoryview tests
* Update memoryview test from buffer to check signedness
* Use static factory method to create memoryview
* Remove ndim arg from memoryview::frombuffer and add tests
* Allow ndim=0 memoryview and documentation fixup
* Use void* to align to frombuffer method signature
* Add const variants of frombuffer and frommemory
* Add memory view section in doc
* Fix docs
* Add test for null buffer
* Workaround py27 nullptr behavior in test
* Rename frombuffer to from_buffer
diff --git a/docs/Doxyfile b/docs/Doxyfile
index 1b9d129..24ece0d 100644
--- a/docs/Doxyfile
+++ b/docs/Doxyfile
@@ -18,3 +18,5 @@
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = NO
+PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS \
+ PY_MAJOR_VERSION=3
diff --git a/docs/advanced/pycpp/numpy.rst b/docs/advanced/pycpp/numpy.rst
index 3d9c90c..aef7abe 100644
--- a/docs/advanced/pycpp/numpy.rst
+++ b/docs/advanced/pycpp/numpy.rst
@@ -384,3 +384,45 @@
py::array a = /* A NumPy array */;
py::array b = a[py::make_tuple(0, py::ellipsis(), 0)];
+
+Memory view
+===========
+
+For a case when we simply want to provide a direct accessor to C/C++ buffer
+without a concrete class object, we can return a ``memoryview`` object. Suppose
+we wish to expose a ``memoryview`` for 2x4 uint8_t array, we can do the
+following:
+
+.. code-block:: cpp
+
+ const uint8_t buffer[] = {
+ 0, 1, 2, 3,
+ 4, 5, 6, 7
+ };
+ m.def("get_memoryview2d", []() {
+ return py::memoryview::from_buffer(
+ buffer, // buffer pointer
+ { 2, 4 }, // shape (rows, cols)
+ { sizeof(uint8_t) * 4, sizeof(uint8_t) } // strides in bytes
+ );
+ })
+
+This approach is meant for providing a ``memoryview`` for a C/C++ buffer not
+managed by Python. The user is responsible for managing the lifetime of the
+buffer. Using a ``memoryview`` created in this way after deleting the buffer in
+C++ side results in undefined behavior.
+
+We can also use ``memoryview::from_memory`` for a simple 1D contiguous buffer:
+
+.. code-block:: cpp
+
+ m.def("get_memoryview1d", []() {
+ return py::memoryview::from_memory(
+ buffer, // buffer pointer
+ sizeof(uint8_t) * 8 // buffer size
+ );
+ })
+
+.. note::
+
+ ``memoryview::from_memory`` is not available in Python 2.