title: Returning and passing around raw POD pointers (arrays) with Python, C++, and pybind11
body: <p>I have a C++ function which returns a raw <code>float</code> pointer, and another C++ function which accepts a raw <code>float</code> pointer as an argument. Something like:</p>
  
  <pre><code>float* ptr = something;
  float* get_ptr(void) { return ptr; }
  void use_ptr(float* ptr) { do_work(ptr); }
  </code></pre>
  
  <p>I want to be able to pass around pointers using Python. Something like this:</p>
  
  <pre><code>import my_native_functions as native
  ptr = native.get_ptr()
  native.use_ptr(ptr)
  </code></pre>
  
  <p>I am using pybind11 to create my native python module but I don't know how to create the bindings for the <code>get_ptr()</code> function. If I just do the following:</p>
  
  <pre><code>PYBIND11_MODULE(my_native_functions, m)
  {
      m.def("get_ptr", &amp;get_ptr);
      m.def("use_ptr", &amp;use_ptr);
  }
  </code></pre>
  
  <p>the <code>get_ptr()</code> function returns a Python <code>Float</code> object. I guess this makes sense because there are no pointer types in python. However, because this is now a simple <code>Float</code>, when I call the <code>use_ptr()</code> function and iterate over the pointer in C/C++, only the first element of the array is correct. The rest are garbage. To fix this, in C++, I have to cast my pointer to/from <code>std::size_t</code>. By doing this, everything works just fine. </p>
  
  <p>However, I would like to ask: Is there a "right way" of achieving the above without the casting to/from <code>std::size_t</code> with pybind11? </p>
  
  <p>In case you are curious why I do that:
  I do understand that what I am doing is not type-safe. Also, I never touch the pointer/integer on the Python side. I just retrieve it from one native module and pass it to another. Also, I cannot cast the pointer to some kind of numpy view because the pointer is not always on the CPU. Sometimes I want to pass around CUDA pointers. Creating a <code>py::array_t</code> from a CUDA pointer is not possible unless I copy the data (and I do not want to do that).</p>
  
  <p>Thank you.</p>