Search code examples
pythonpybind11

How can legacy function returning PyObject * be integrated in a solution based on pybind11?


Working on migrating from swig to pybind11 for exposing C++ to python.

One of the functions is implemented purely in basic Py* API such as PyDict_New, PyUnicode_FromString, PyDict_SetItemString. It returns a PyObject *, i.e.

PyObject *foo(const std::string& file) {
...
}

For now I would just like to reuse this piece of C. But how can I integrate that in the pybind11 solution?


Solution

  • pybind11 has a mechanism for dealing with such a case. See reinterpret_steal: https://github.com/pybind/pybind11/blob/master/include/pybind11/pytypes.h#L463. In your example, assuming foo returns a PyObject* that points to a python string, you would call pybind11::str str = pybind11::reinterpret_steal<pybind11::str>(foo("some string")). Be careful with object lifetimes and ownership here. reinterpret_steal will claim ownership of the object and will destruct it when the object it returns goes out of scope. If your code base already has a mechanism for managing ownership of python objects and you would like to keep that system in place, use reinterpret_borrow https://github.com/pybind/pybind11/blob/master/include/pybind11/pytypes.h#L450 instead, which will not claim ownership of the underlying object.