адрес памяти объекта между python и c ++ не идентичен - PullRequest
0 голосов
/ 08 мая 2019

Я пытаюсь напечатать адрес памяти одного и того же объекта в c ++ и python с помощью pybind11, но обнаружил, что возвращенный адрес памяти из обоих не идентичен.

c ++ сторона

class Example {
  public:
    Example() {std::cout << "constuctor" << this << std::endl;}
    ~Example() {std::cout << "destructor " << this << std::endl;}
};

class ABC {
  public:
    static std::unique_ptr<Example> get_example() {
      // std::shared_ptr<Example> ptr = std::make_shared<Example>();
      std::unique_ptr<Example> ptr = std::make_unique<Example>();
      return ptr;
    }
};

void init_example(py::module & m) {
    py::class_<ABC>(m, "ABC")
    .def_static("get_example", &ABC::get_example);
}

сторона питона

example = my_module.ABC.get_example()
print (example)

выход

constuctor0x234cd80
<Example object at 0x7f5493c37928>
destructor 0x234cd80

адрес памяти в c ++ - 0x234cd80, а python - 0x7f5493c37928

Есть идеи?

Ответы [ 2 ]

1 голос
/ 10 мая 2019

pybind11 создает объект Python, который имеет ссылку на объект C ++.Таким образом, адреса оболочки Python pybind11 и объекта C ++ различны.

Адрес в представлении объекта pybind11 str по умолчанию является адресом объекта python, а не базового объекта C ++ или его интеллектуального указателя.

Если вам нужно узнать адрес объекта C ++, добавьте метод связывания кода, как предложено @PaulMcKenzie.

C ++:

namespace py = pybind11;

PYBIND11_MODULE(example_module, m){
  m.def("add", add);

  py::class_<Example>(m,"Foo")
      .def(py::init())
      .def("get_raw_address",[](Example& foo){ return reinterpret_cast<uint64_t>(&foo);});

}

Python:

example = Example()
print(example)
print("C++ address: %x" % example.get_raw_address())

Вывод:

constuctor 0x10eff20
<example_module.Foo object at 0x7f51c71d4298>
C++ address: 10eff20
destructor 0x10eff20
1 голос
/ 08 мая 2019

Я не знаком с аспектом Python в этом вопросе, но, концентрируясь на части C ++, вы не печатаете правильную информацию.

std::unique_ptr имеет адрес, отличный от создаваемого экземпляра Example, поэтому значения будут другими. Если вы хотите напечатать адрес элемента, к которому обращается unique_ptr, вам нужно вызвать функцию get().

Вот полный пример, показывающий различия:

#include <memory>
#include <iostream>

class Example {
  public:
    Example() {std::cout << "constuctor " << this << std::endl;}
    ~Example() {std::cout << "destructor " << this << std::endl;}
};

class ABC {
  public:
    static std::unique_ptr<Example> get_example() 
    {
      std::unique_ptr<Example> ptr = std::make_unique<Example>();
      return ptr;
    }
};

int main()
{
    std::unique_ptr<Example> p = ABC::get_example();
    std::cout << "The unique_ptr address is: " << &p << std::endl;
    std::cout << "The get() function returns: " << p.get() << std::endl;
}

Выход:

constuctor 0x555a68bd7c20
The unique_ptr address is: 0x7ffd9fa6c120
The get() function returns: 0x555a68bd7c20
destructor 0x555a68bd7c20

Таким образом, вам нужно настроить свой код Python для вывода возвращаемого значения get().

...