Sunday 8 November 2020

Increase ref_count of pybind11 handle in C++

I have a virtual object that I subclass and implement in python using pybind11, and that object then is used in C++ code but the python object goes out of scope when the python script finished and python garbage collector destroys my object before I can use it in C++ side.

To avoid the destruction I have added a "keep" method to the binding code that increases the ref_count, so that python garbage collector doesn't destroy it.

C++ code for the bindings

VNCS::Real VNCS::py::BlendingField::blending(const VNCS::Point_3 &p) const
{
    std::array<double, 3> pyP{p[0], p[1], p[2]};
    PYBIND11_OVERLOAD_PURE(VNCS::Real,          /* Return type */
                           VNCS::BlendingField, /* Parent class */
                           blending,            /* Name of function in C++ (must match Python name) */
                           pyP                  /* Argument(s) */
    );
}

void VNCS::py::module::blendingField(pybind11::module &m)
{
    pybind11::class_<VNCS::BlendingField, VNCS::py::BlendingField, std::shared_ptr<VNCS::BlendingField>>(
        m, "BlendingField")
        .def(pybind11::init(
            [](pybind11::args &args, pybind11::kwargs &kwargs) { return std::make_shared<VNCS::py::BlendingField>(); }))
        .def("keep", [](pybind11::handle handle) { handle.inc_ref(); });
}

Python code

class BlendingField(PyVNCS.BlendingField):
   def __init__(self, *args, **kwargs):
      PyVNCS.BlendingField.__init__(self, *args, **kwargs)

   def __del__(self):
       print("dtor from python")

   def blending(self, point):
       return point[0]

blendingField = BlendingField()
blendingField.keep()
simCreator = initObject.addObject("SimCreator",
                     name="simCreator",
                     coarseMesh="@lowResTopology",
                     detailMesh="@highResTopology")
simCreator.setBlendingField(blendingField)

This doesn't look very nice, as the keep method there feels like a terrible hack. What would be the correct way to implement this?



from Increase ref_count of pybind11 handle in C++

No comments:

Post a Comment