title: returning multiple py::array without copying in pybind11
body: <p>I am trying to build a python module in C++ using pybind11. I have the following code:</p>
  
  <pre><code>#include &lt;pybind11/pybind11.h&gt;
  #include &lt;pybind11/stl.h&gt;
  #include &lt;pybind11/numpy.h&gt;
  
  namespace py = pybind11;
  
  struct ContainerElement
  {
      uint8_t i;
      double d;
      double d2;
  };
  
  class Container
  {
  private:
      std::vector&lt;uint8_t&gt; ints;
      std::vector&lt;double&gt; doubles;
      std::vector&lt;double&gt; doubles2;
  
  public:
  
      std::vector&lt;uint8_t&gt;&amp; getInts() { return ints; }
      std::vector&lt;double&gt;&amp; getDoubles() { return doubles; }
      std::vector&lt;double&gt;&amp; getDoubles2() { return doubles2; }
  
      void addElement(ContainerElement element)
      {
          ints.emplace_back(element.i);
          doubles.emplace_back(element.d);
          doubles2.emplace_back(element.d2);
      }
  };
  
  void fillContainer(Container&amp; container)
  {
      for (int i = 0; i &lt; 1e6; ++i)
      {
          container.addElement({(uint8_t)i, (double)i,(double)i });
      }
  }
  
  PYBIND11_MODULE(containerInterface, m) {
      py::class_&lt;Container&gt;(m, "Container")
          .def(py::init&lt;&gt;())
          .def("getInts", [](Container&amp; container)
          {
              return py::array_t&lt;uint8_t&gt;(
                      { container.getInts().size() },
                      { sizeof(uint8_t) },
                      container.getInts().data());
          })
          .def("getDoubles", [](Container&amp; container)
          {
              return py::array_t&lt;double&gt;(
                      { container.getDoubles().size() },
                      { sizeof(double) },
                      container.getDoubles().data());
          })
          .def("getDoubles2", [](Container&amp; container)
          {
              return py::array_t&lt;double&gt;(
                      { container.getDoubles2().size() },
                      { sizeof(double) },
                      container.getDoubles2().data());
          });
  
      m.def("fillContainer", &amp;fillContainer);
  }
  </code></pre>
  
  <p>When I call this code in python:</p>
  
  <pre><code>import containerInterface
  
  container = containerInterface.Container()
  
  containerInterface.fillContainer(container)
  
  i = container.getInts()
  d = container.getDoubles()
  d2 = container.getDoubles2()
  </code></pre>
  
  <p>This works, however when I check the memory usage of the program (using <code>psutil.Process(os.getpid()).memory_info().rss</code>) it seems to make a copy when I call the functions <code>getInts, getDoubles</code> and <code>getDoubles2</code>. Is there a way to avoid this?</p>
  
  <p>I have tried using <code>np.array(container.getInts(), copy=False)</code>, but it still makes a copy. Also I tried using the <code>py::buffer_protocol()</code> on the Container class as mentioned here: <a href="https://pybind11.readthedocs.io/en/stable/advanced/pycpp/numpy.html" rel="noreferrer">https://pybind11.readthedocs.io/en/stable/advanced/pycpp/numpy.html</a> . However I can only make that work for either the Ints vector or the Doubles vectors and not for all at the same time.</p>
  
  <pre><code>PYBIND11_MODULE(containerInterface, m) {
      py::class_&lt;Container&gt;(m, "Container", py::buffer_protocol())
          .def(py::init&lt;&gt;())
          .def("getInts", &amp;Container::getInts)
          .def("getDoubles", &amp;Container::getDoubles)
          .def_buffer([](Container&amp; container) -&gt; py::buffer_info {
              return py::buffer_info(
                  container.getInts().data(),
                  sizeof(uint8_t),
                  py::format_descriptor&lt;uint8_t&gt;::format(),
                  1,
                  { container.getInts().size() },
                  { sizeof(uint8_t) * container.getInts().size() }
          );
          });
  m.def("fillContainer", &amp;fillContainer);
  </code></pre>
  
  <p>Then I can use <code>i = np.array(container, copy=False)</code>, without a copy being made. However as I said it only works for the <code>Ints</code> vector now.</p>