用pybind11包装一个C ++分配的实例

时间:2019-10-08 07:29:25

标签: python c++ pybind11

通过PyBind11在C ++中嵌入python时,我陷入了以下问题。考虑到我通过C ++生成了一个对象的shared_ptr实例,然后我希望将此指针移交给pybind11来为其生成“阴影” python绑定。

这是我最初的无效尝试:

#include <stdio.h>
#include <pybind11/pybind11.h>
#include <pybind11/embed.h>

using namespace std;
namespace py = pybind11;

class Pet 
{
public:
    Pet() {}
    void bark(void) { printf("wow!\n"); }
};

PYBIND11_PLUGIN(Pets) {
    py::module m("Pets", "Say hello to our pets");

    py::class_<Pet, shared_ptr<Pet>>(m, "Pet")
        .def("bark", &Pet::bark)
      ;
    return m.ptr();
}

int main(int argc, char *argv[])
{
  py::scoped_interpreter guard{};
  shared_ptr<Pet> pet = make_shared<Pet>();

  // How do Ι "assign" Pet.pet to the C++ pet? This compiles,
  // but throws a run time exception:
  py::globals()["pet"] = py::cast(pet);

  py::exec("pet.bark()\n");
}

所以我的问题是:

  • 那么如何为C ++ shared_ptr创建一个“影子类”?
  • 如何将C ++ shared_ptr“分配”给python变量?

1 个答案:

答案 0 :(得分:2)

如果您从强制转换检查生成的py :: object(例如,将其强制转换为bool),则会看到调用失败。原因是python不知道“ Pet”类(也不知道shared_ptr)。您可以使用上面的代码并以通常的方式从中创建一个模块,然后将其导入到主程序中。或者,使用EMBEDDED_MODULE功能,该功能更接近您想要的功能。

调整示例:

#include <stdio.h>
#include <pybind11/pybind11.h>
#include <pybind11/embed.h>

using namespace std;
namespace py = pybind11;

class Pet
{
public:
    Pet() {}
    void bark(void) { printf("wow!\n"); }
};

PYBIND11_EMBEDDED_MODULE(Pets, m) {
    py::class_<Pet, shared_ptr<Pet>>(m, "Pet")
        .def("bark", &Pet::bark)
    ;
}

int main(int argc, char *argv[])
{
  py::scoped_interpreter guard{};
  shared_ptr<Pet> pet = make_shared<Pet>();

  auto pets_mod = py::module::import("Pets");

  py::globals()["pet"] = py::cast(pet);
  py::exec("pet.bark()\n");
}