2009-10-26 67 views
1

尝试使用父子关系在C++中设置依赖项。父项包含子项,并且子项具有指向父项的弱指针。使用Boost Python与弱点?

我也希望能够从Python中的父类派生。但是,当我这样做时,我得到一个弱指针错误连接这个父子关系。

C++代码:

#include <boost/python.hpp> 
#include <boost/shared_ptr.hpp> 
#include <boost/enable_shared_from_this.hpp> 

using namespace boost; 
using namespace boost::python; 

struct Child; 

struct Parent : public enable_shared_from_this<Parent> 
{ 
    void initialize(); 
    shared_ptr<Child> m_child; 
}; 

struct Child: public enable_shared_from_this<Child> 
{ 
    void setParent(shared_ptr<Parent> ptr); 
    weak_ptr<Parent> m_parent; 
}; 

void Parent::initialize() 
{ 
    shared_ptr<Child> ptr(new Child); 
    m_child = ptr; 

    m_child->setParent(shared_from_this()); 
} 

void Child::setParent(shared_ptr<Parent> ptr) 
{ 
    m_parent = ptr; 
} 

static PyObject* create(PyObject* object) 
{ 
    PyObject* instance = PyObject_CallObject(object, NULL); 

    Parent* parent = extract<Parent*>(instance); 
    parent->initialize(); 

    return instance; 
} 

Python绑定:

BOOST_PYTHON_MODULE(test_module) 
{ 
    class_<Parent>("Parent"); 

    def("create", &create); 
} 

Python代码:

from test_module import * 

class Test(Parent): 
    def __init__(self): 
     Parent.__init__(self) 

n = create(Test) 

错误:

Traceback (most recent call last): 
    File "main.py", line 8, in <module> 
    n = create(Test) 
RuntimeError: tr1::bad_weak_ptr 

如果我尝试将提取的指针转换为父对象为shared_ptr,那么Python中会出现free()无效指针错误。

有没有办法绕过这个问题,或者我应该放弃使用Boost Python的弱指针?

回答

2

我玩的代码没有python的东西。

此重现问题:

Parent* p(new Parent); 
p->initialize(); 

的问题是什么是抱着到shared_ptr的对象。 这修复它:

boost::shared_ptr<Parent> p(new Parent); 
p->initialize(); 

Boost.Python的常见问题:“当一个shared_ptr从Python的转换,则实际的shared_ptr管理一个参照含有Python对象当一个shared_ptr转换回Python中,库检查看看它是否是那些“Python对象管理器”之一,如果是这样,只是返回原始Python对象“父*”需要以某种方式存储在shared_ptr中。我还没有想出如何。

Parent* parent = boost::python::extract<Parent*>(instance); 
1

class_的接口允许您控制对象的保持方式。它是一个名为HeldType的模板参数。关于class_的Boost.Python文档中有更多信息,但是您的Python绑定可能看起来更像这样:

class_<Parent, boost::shared_ptr<Parent> >("Parent");