Search code examples
c++pybind11

Pybind11 keep_alive of std::string


Consider this pybind11 C++ code, with a getter and a setter:

struct Properties { const char* p; };

// getter, setter as lambda
.def_property(
          "some_attribute",
          [](Properties &prop) {
            std::string s = prop.p;
            return s;
          },
          py::cpp_function(
          [](Properties &prop, std::string &s) {
            prop.p= s.c_str(); // something is char*
          }, py::keep_alive<1,2>()));

Is the above the correct way to make sure std::string& s in the setter part will be kept alive for the lifetime duration of prop?


Solution

  • Seems like the correct way to do this, per this link is to strdup it or any similar allocation, and use return_value_policy::take_ownership or return_value_policy::automatic which falls back to return_value_policy::take_ownership in case of pointer.

    To post a complete example based on the above:

    struct Properties { const char* p; };
    
    // getter, setter as lambda
    .def_property(
              "some_attribute",
              [](Properties &prop) {
                std::string s = prop.p;
                return s;
              },              
              [](Properties &prop, std::string &s) {
                prop.p = strdup(s.c_str());
              }, py::return_value_policy::take_ownership);