Pybind:从 C++ 朋友那里访问指向的值 class

Pybind: Accessing pointed values from C++ friend class

我正在尝试在 PyBind11 中处理 friend classes 中的指针。问题是我无法检索 Python 中朋友 class 对象的指向值。玩具示例有效,但值与应有的值完全不同。

我一开始以为是朋友class的缘故,但根据我的阅读和理解,我认为不是。我也无法在 documentation.

中找到任何内容

example.cpp

#include <pybind11/pybind11.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <list>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>

namespace py = pybind11;

class Owner;
class Pet {

    friend Owner;

    public:
      std::string name;
      int a;
      Pet(const std::string name_, int b){
          name = name_;
          a = b;
      }

      Pet(const std::string name_){
        name = name_;
        a = 23;
      }

    int repr(){
      return a;
    }
};

class Owner {

      public:
        int owner_id;
        Pet* their_pet;

      Owner(int owner_id_, Pet *their_pet_){
        owner_id = owner_id_;
        their_pet = their_pet_;
      }
};


int retrieve(py::handle the_owner){
  Owner an_owner = the_owner.cast<Owner>();
  Pet* the_retrieved_pet = an_owner.their_pet;
  int the_age = the_retrieved_pet->repr();
  std::cout << the_age << std::endl;
  return the_age;
}

py::object create_neat(){

  Pet dog = Pet("rufus", 2);
  Pet* ptr_dog = &dog;
  Owner owner_1 = Owner(1, ptr_dog);
  py::object py_owner = py::cast(owner_1);
  return py_owner;

}

PYBIND11_MODULE(example, m){
  py::class_<Pet>(m, "Pet")
      .def(py::init<const std::string>())
      .def("repr", &Pet::repr);

  py::class_<Owner>(m, "Owner");

  m.def("retrieve", &retrieve, "return the python object to its class");

  m.def("create_neat", &create_neat, "return the python object to its class");
}

可编译:

g++ -O3 -Wall -fopenmp -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example.so

在Python

import example

a = example.create_neat()
b = example.retrieve(a)

b 应该是 2,相反,它是一个完全不同的值。

独立于pybind "magic",函数create_neat()实例化一个局部变量

Pet dog = Pet("rufus", 2);

然后将其地址传递给 Owner 实例。此地址生命周期仅为 create_neat() 函数范围,因此一旦 create_neat() 函数 returns 就不会发生任何好事。当 create_neat() 函数 returns

时狗地址将指向任何东西