将 Boost Python 与弱指针一起使用?
尝试在 C++ 中建立具有父子关系的依赖关系。父级包含子级,子级有一个指向父级的弱指针。
我还希望能够从 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
如果我尝试将提取的指向 Parent 的指针转换为共享指针,我会在 Python 中收到 free() 无效指针错误。
有没有办法解决这个问题,或者我应该放弃在 Boost Python 中使用弱指针?
Trying to set up a dependency in C++ with a parent-child relationship. The parent contains the child and the child has a weak pointer to the parent.
I would also like to be able to derive from the parent in Python. However, when I do this, I get a weak pointer error connecting up this parent-child relationship.
C++ code:
#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 binding:
BOOST_PYTHON_MODULE(test_module)
{
class_<Parent>("Parent");
def("create", &create);
}
Python code:
from test_module import *
class Test(Parent):
def __init__(self):
Parent.__init__(self)
n = create(Test)
Error:
Traceback (most recent call last):
File "main.py", line 8, in <module>
n = create(Test)
RuntimeError: tr1::bad_weak_ptr
If I try and convert the extracted pointer to Parent into a shared_ptr, I get a free() invalid pointer error in Python.
Is there a way of getting round this problem or should I give up using weak pointers with Boost Python?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在没有 python 的情况下玩了代码。
这重现了问题:
问题是没有任何东西保留在shared_ptr对象上。
这修复了它:
Boost.Python FAQ:“当从Python转换shared_ptr时,shared_ptr实际上管理对包含Python对象的引用。当shared_ptr转换回Python时,库检查它是否是其中之一“ Python 对象管理器”,如果是这样,则仅返回原始 Python 对象”
Parent* 需要以某种方式存储在 shared_ptr 中。我还没想出怎么办
I played with the code without the python stuff.
This reproduced the problem:
The problem is nothing is holding on to the shared_ptr object.
This fixes it:
Boost.Python FAQ : "When a shared_ptr is converted from Python, the shared_ptr actually manages a reference to the containing Python object. When a shared_ptr is converted back to Python, the library checks to see if it's one of those "Python object managers" and if so just returns the original Python object"
The Parent* needs to be stored in a shared_ptr somehow. I haven't figured out how yet.
class_ 的接口允许您控制对象的持有方式。它是一个名为 HeldType 的模板参数。 Boost.Python 文档中有关于 class_ 的更多信息,但您的 Python 绑定可能看起来更像这样:
The interface of class_ allows you to control how the object is held. It is a template parameter called HeldType. There is more information in the Boost.Python documentation on class_, but your Python binding might look more like this: