2009-10-26 63 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");