'pybind11: how to convert a C++ function that return pointer?

How to convert a C++ function that return pointer? Just like:

int * getRandom( )
{
  static int  r[10];
 
  srand( (unsigned)time( NULL ) );
  for (int i = 0; i < 10; ++i)
  {
    r[i] = rand();
    cout << r[i] << endl;
  }
 
  return r;
}

How should I bind to convert this C++ function to python?

m.def("getRandom", &getRandom, py::return_value_policy::reference);

The above method can only return the first number of the array. In python side, How should I do to get the array value with length of 10 that function getRandom generate in C++ code.



Solution 1:[1]

Like this

#include <pybind11/numpy.h>

// ...

pybind11::array_t<int> getRandomWrapper(void)
{
    int* values = getRandom();

    pybind11::capsule cleanup(values, [](void *f) {});

    return pybind11::array_t<int>(
       {10},          // shape
       {sizeof(int)}, // stride
       values,   // pointer to data
       cleanup        // garbage collection callback
    );
}

and then just

m.def("getRandom", &getRandomWrapper);

(return_value_policy::reference is not appropriate here as you are not directly referencing r.)

The fourth argument to the array_t<int> constructor is a wrapper or "capsule" around a function that describes how to free the array's underlying memory. In this case you are returning a pointer to something managed by "automatic storage" so there is nothing to cleanup, hence it does nothing.

If, on the other hand, you were dynamically allocating the returned array you would need something like

pybind11::capsule cleanup(values, [](void *f) {
    delete[] static_cast<int*>(values);
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1