Pybind: доступ к указанным значениям из класса друзей C ++ - PullRequest
0 голосов
/ 10 апреля 2020

Я пытаюсь обработать указатели в классах друзей в PyBind11. Проблема в том, что я не могу получить указанные значения объекта класса друга в Python. Игрушечный пример работает, но значения полностью отличаются от того, какими они должны быть. Первоначально я думал, что это будет из-за класса друга, но, согласно моим прочтениям и пониманию, я так не думаю. Я также не смог найти ничего в документации

, например. 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

In Python

import example

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

b должно быть 2, и вместо этого это совершенно другое значение. Любая помощь будет более чем признательна.

1 Ответ

0 голосов
/ 10 апреля 2020

Независимо от pybind "magi c", функция create_neat () создает локальную переменную

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

, а затем передает ее адрес экземпляру Owner. Этот срок жизни адреса является только областью действия функции create_neat (), поэтому ничего хорошего не произойдет, когда функция create_neat () вернется. Адрес собаки будет указывать на что угодно, когда функция create_neat () возвращает

...