通过 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++ 类 FooBaz 我已经通过 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&lt;planning_scene::PlanningScene&gt;)的共享指针,其中该类被声明为,

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_sharedFoo 构造函数中创建的PlanningScene 实例。

运行一些 C++ 集成测试工作正常,我直接在 C++ 中将 foo_ptrFoo 传递到 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 对象的新引用

扩展通过 Boost.Python 公开的虚拟 C++ 类

使用 c++ 对象的全局实例扩展嵌入式 python 解释器

如何使用 PyObjects 声明 Boost.Python C++ 类

python调c++之caffe实现

如何在 boost::python 扩展模块中正确组合 C++ 和 Python 代码?