【问题标题】:Boost python object lifetime提升python对象的生命周期
【发布时间】:2012-07-20 19:57:32
【问题描述】:

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);
}

蟒蛇:

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(); }

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

【问题讨论】:

    标签: c++ python boost garbage-collection


    【解决方案1】:

    如果你想存储这个指针,你必须增加底层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 ) );
    }
    

    【讨论】:

    • 你能在std::pair 中有Foo&amp; 吗?
    • 是的,你可以拥有。它只不过是一个“指针”。但是您必须确保在删除后不访问该对象,这是通过递增和存储引用(对象)来确保的。
    猜你喜欢
    • 1970-01-01
    • 2012-12-26
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    相关资源
    最近更新 更多