c++ - boost python 对象的生命周期

标签 c++ python boost garbage-collection

cpp:

#include <boost/python.hpp>

using namespace boost;
using namespace boost::python;

struct Foo
{
   virtual ~Foo() {}
   virtual void Print() = 0;
};

struct FooWrap : Foo, wrapper<Foo>
{
    void Print()
    {
        this->get_override("Print")();
    }
};

void ProcessFoo(Foo *obj) { obj->Print(); }

BOOST_PYTHON_MODULE(hello_ext)
{
    class_<FooWrap, boost::noncopyable>("Foo")
        .def("Print", pure_virtual(&Foo::Print));
    def("ProcessFoo", &ProcessFoo);
}

python :

import hello_ext

class NewFoo(hello_ext.Foo):
   def Print(self):
      print 'Print call'

hello_ext.ProcessFoo( NewFoo() )

一切正常,ProcessFoo 调用中有 Print call 文本。但我想存储所有传递给 ProcessFoo 的指针,例如:

std::vector<Foo*> data;
void ProcessFoo(Foo *obj) { data.push_back(obj); obj->Print(); }

从函数指针退出后变得无效,我不能从 vector 中使用它。使该指针的生命周期更长的最佳方法是什么?使用共享指针或告诉 python 不要删除对象(如果它删除它?)

最佳答案

如果你想存储这个指针,你必须增加底层 python 对象 (PyObject) 的引用计数。为此,你必须实现你的 void ProcessFoo(Foo *obj) 来获取 python 对象而不是 C++ 对象,否则 boost::python 将在他的适应中为你剥离 python 对象,你无法再控制它的生命周期。

如果你这样做,你还必须明确地转换为你的 C++ 类型(但使用 boost::python 这不是那么麻烦)。

using namespace boost::python;
std::vector< std::pair<object, Foo&> > myVec;

void ProcessFoo(object o )
{
  Foo& x = extract<Foo&>(o);
  // ... do you add to container here, but remember, to add the object o
  // too, otherwise the refernce counter will be decremented and the object
  // may go away.
  myVec.push_back( std::make_pair( o, x ) );
}

关于c++ - boost python 对象的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11586173/

相关文章:

python - 安全存储 Redis 密码

python - 多类问题的单热编码类标签的正确方法

c++ - 实现扩展内省(introspection)交换算法

c++ - 将 uint32_t 转换为 uint64_t 会产生不同的值?

c++ - 混合 shared_ptr 和普通 ptr

c++ - 如何使用 gtk 中的代码将单选按钮设置为选中状态?

c++ - 您如何使用任何 Boost 多精度库类型找到两个非常大的数字的模逆? (cpp_int、gmp_int 等)

python - 如何自动检测 Pandas 数据框中包含日期时间的列

c++ - async_connect 在 boost::asio 中阻塞 io_service::run_one()

c++ - 我可以安全地指向重新分配的 boost::optional 的数据吗?