gpt4 book ai didi

python - 在 pybind11 中引用 C++ 分配的对象

转载 作者:行者123 更新时间:2023-11-30 01:42:18 24 4
gpt4 key购买 nike

我正在尝试使用 pybind11 创建一个 python 绑定(bind),它引用一个 C++ 实例,其内存在 C++ 端处理。下面是一些示例代码:

import <pybind11/pybind11>

struct Dog {
void bark() { printf("Bark!\n"); }
};

int main()
{
auto dog = new Dog;
Py_Initialize();
initexample(); // Initialize the example python module for import

// TBD - Add binding between dog and example.dog .

PyRun_StringFlags("import example\n"
"\n"
"example.dog.bark()\n" // Access the C++ allocated object dog.
, Py_file_input, main_dict, main_dict, NULL);
Py_Finalize();
}

我卡在如何在 python example.dog 之间创建链接和 C++ dog多变的。

我不能使用 py:class_<Dog>.def(py::init<>())因为这将分配一个新实例 Dog ,这不是我想要的。

最佳答案

我找到了我自己问题的答案。技巧是以下两个概念的组合:

  • 创建一个返回单例的独立函数。
  • 创建到单例类的绑定(bind)而不绑定(bind)构造函数。

以下示例说明了该技术:

#include <Python.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;
using namespace pybind11::literals;

// Singleton to wrap
struct Singleton
{
Singleton() : x(0) {}

int exchange(int n) // set x and return the old value
{
std::swap(n, x);
return n;
}

// Singleton reference
static Singleton& instance()
{
static Singleton just_one;
return just_one;
}

int x;
};

PYBIND11_PLUGIN(example) {
py::module m("example", "pybind11 example plugin");

// Use this function to get access to the singleton
m.def("get_instance",
&Singleton::instance,
py::return_value_policy::reference,
"Get reference to the singleton");

// Declare the singleton methods
py::class_<Singleton>(m, "Singleton")
// No init!
.def("exchange",
&Singleton::exchange,
"n"_a,
"Exchange and return the current value"
)
;

return m.ptr();
}

int main(int argc, char **argv)
{
Py_Initialize();

PyObject* main_module = PyImport_AddModule("__main__");
PyObject* main_dict = PyModule_GetDict(main_module);

initexample();

// Call singleton from c++
Singleton::instance().exchange(999);

// Populate the example class with two static pointers to our instance.
if (PyRun_StringFlags("import example\n"
"\n"
"example.s1 = example.get_instance()\n"
"example.s2 = example.get_instance()\n",
Py_file_input, main_dict, main_dict, NULL) == nullptr)
PyErr_Print();

// Test referencing the singleton references
if (PyRun_StringFlags("from example import *\n"
"\n"
"for i in range(3):\n"
" print s1.exchange(i*2+1)\n"
" print s2.exchange(i*2+2)\n"
"print dir(s1)\n"
"print help(s1.exchange)\n"
,
Py_file_input, main_dict, main_dict, NULL) == nullptr)
PyErr_Print();

Py_Finalize();

exit(0);
}

关于python - 在 pybind11 中引用 C++ 分配的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39860405/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com