通过 Boost Python 在 C++ 对象之间传递共享指针的 Segfault
Posted
技术标签:
【中文标题】通过 Boost Python 在 C++ 对象之间传递共享指针的 Segfault【英文标题】:Segfault from passing a shared pointer between C++ objects via Boost Python 【发布时间】:2018-05-06 16:31:53 【问题描述】:我有两个自定义 C++ 类 Foo
和 Baz
我已经通过 Boost Python 成功地接触了 Python;用户与运行 C++ 对应的 Python 类进行交互。一个重要的用例是将Foo
Python 实例传递给Python 方法Baz.run_that_foo
。 Python 绑定方法是,
// Note `XPython` is the name for the Boost Python bindings class of `X`.
void BazPython::RunThatFoo(const bp::object & foo)
FooPython & foo_obj = bp::extract<FooPython&>(foo);
auto ps_ptr = foo_obj.GetPSPtr();
Baz::DoPSComputation(ps_ptr); // Expects a `const std::shared_ptr<planning_scene::PlanningScene>`
重要的是,ps_ptr
应该是指向 PlanningScene 实例(即std::shared_ptr<planning_scene::PlanningScene>
)的共享指针,其中该类被声明为,
class PlanningScene : private boost::noncopyable, public std::enable_shared_from_this<PlanningScene>
在我拥有的 C++ Foo
类中,
std::shared_ptr<planning_scene::PlanningScene> Foo::GetPSPtr() // two different attempts shown
// return ps_;
return (*ps_).shared_from_this();
其中ps_
是一个有效的共享指针,指向通过std::make_shared
在Foo
构造函数中创建的PlanningScene 实例。
运行一些 C++ 集成测试工作正常,我直接在 C++ 中将 foo_ptr
从 Foo
传递到 Baz
。但是 python 集成测试(使用绑定类)在Segmentation fault (core dumped)
上失败。这里有什么问题?我已经在 Boost Python segfaults、enable_shared_from_this
等方面挖掘了许多 SO 问题,但无济于事。提前致谢!
【问题讨论】:
您确定 Python 接口需要 shared_ptr 而不是原始指针吗? 好电话@JiveDadson:根据this Boost Python issue,看起来Boost Python 不支持C++ 11 std::shared_ptr,直到v1.63.0。不幸的是,std::enable_shared_from_this
需要使用 std::
而不是 boost::
共享指针,并且我坚持使用 boost v1.58.0 以便与我的项目中的其他包兼容。
使用 shared_ptr::get() 将原始指针传递给 Python?
像 PIMPL 模式这样的东西呢?将共享的ptr放入一个struct,并添加一些转发方法。
好建议@DanMašek,我不熟悉PImpl pattern。我刚刚发布的解决方案以手动方式执行此操作 boost::bind
。
【参考方案1】:
诀窍是使用boost::bind
围绕我们从 Python 绑定类(即FooPython.GetPSPtr
)调用的方法生成转发调用包装器:
void BazPython::RunThatFoo(const bp::object & foo)
FooPython & foo_obj = bp::extract<FooPython&>(foo);
Baz::DoPSComputation(boost::bind(&Foo::GetPSPtr, &foo_obj)());
【讨论】:
以上是关于通过 Boost Python 在 C++ 对象之间传递共享指针的 Segfault的主要内容,如果未能解决你的问题,请参考以下文章
Boost.Python 从 C++ 创建对现有 Python 对象的新引用
使用 c++ 对象的全局实例扩展嵌入式 python 解释器