如何使用PyObjects声明Boost.Python C ++类 [英] How can i declare a Boost.Python C++ Class with PyObjects

查看:60
本文介绍了如何使用PyObjects声明Boost.Python C ++类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用PyObjects编写一个c ++类,以便从Python访问它们,以使用现有的Python对象实例引用它们.简而言之,我想在C ++类中存储/管理Python对象实例.

i want to write a c++ class with PyObjects to access them from Python to reference them with an existing Python object instance. In short words i want to store/manage Python object instances in the C++ class.

例如:

struct Var
{
    PyObject *Test_1;
    PyObject *Test_2;

};

#include <boost/python.hpp>
using namespace boost::python;

BOOST_PYTHON_MODULE(Var)
{
    class_<Var>("Var", init<std::string>())
        .def_readwrite("Test_1", &Var::value)
        .def_readwrite("Test_2", &Var::value)
    ;
}

在python中,如果可以使用Boost.Python,我想这样做:

in python i want to do this if it is possible with Boost.Python:

class Test:
    def __init__(self, a = 0, b = 2):
        self.a = 0
        self.b = 0


test = Test(2,2)

import Var
newStore = Var
newStore.Test_1 = test

非常感谢您!

打招呼

Flo

推荐答案

使用Boost.Python在C ++中管理Python对象时,应考虑使用

When managing Python objects in C++ with Boost.Python, one should consider using the boost::python::object class rather than PyObject. The object acts very much like a Python variables, allowing for Python-ish code in C++. Furthermore, they behave similar to a smart pointer, providing referencing counting and lifetime management, where as one would need to explicitly manage the reference count with a PyObject.

这是一个基于原始代码的完整示例,该示例演示了如何使用 boost :: python :: object PyObject :

Here is a complete example based on the original code that demonstrates using boost::python::object and PyObject:

#include <boost/python.hpp>

/// @brief Mockup type that can manage two Python objects.
struct var
{
  boost::python::object test_1; // managed
  PyObject* test_2;             // must explicitly manage

  var()
    : test_2(Py_None)
  {
    Py_INCREF(test_2);
  }

  ~var()
  {
    Py_DECREF(test_2);
  }
};

/// @brief Auxiliary function used to return a non-borrowed reference to
//         self.test_2.  This is necessary because Boost.Python assumes
//         that PyObject* passed from C++ to Python are not borrowed.
PyObject* var_test_2_getter(const var& self)
{
  PyObject* object = self.test_2;
  Py_INCREF(object);
  return object;
}

/// @brief Auxiliary function used to manage the reference count of
///        objects assigned to var.test_2.
void var_test_2_setter(var& self, PyObject* object)
{
  Py_DECREF(self.test_2);
  self.test_2 = object;
  Py_INCREF(self.test_2);
}

BOOST_PYTHON_MODULE(example)
{
  namespace python = boost::python;
  python::class_<var>("Var", python::init<>())
    .def_readwrite("Test_1", &var::test_1)
    .add_property("Test_2", &var_test_2_getter, &var_test_2_setter)
    ;
}

互动用法:

>>> class Test:
...     def __init__(self, a=0, b=2):
...         self.a = a
...         self.b = b
... 
>>> test = Test(2, 2)
>>> from sys import getrefcount
>>> count = getrefcount(test)
>>> import example
>>> store = example.Var()
>>> store.Test_1 = test
>>> assert(store.Test_1 is test)
>>> assert(count + 1 == getrefcount(test))
>>> assert(store.Test_1.a == 2)
>>> store.Test_1.a = 42
>>> assert(test.a == 42)
>>> store.Test_2 = test
>>> assert(store.Test_2 is test)
>>> assert(count + 2 == getrefcount(test))
>>> assert(count + 2 == getrefcount(store.Test_2))
>>> store.Test_2 = None
>>> assert(count + 1 == getrefcount(test))
>>> store = None
>>> assert(count == getrefcount(test))

这篇关于如何使用PyObjects声明Boost.Python C ++类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆