【问题标题】:Is it possible to pass a boost shared_ptr from C++ to Python and back to C++是否可以将 boost shared_ptr 从 C++ 传递到 Python 并返回到 C++
【发布时间】:2012-08-25 19:40:22
【问题描述】:

我有一个对象保存在 C++ 中的 shared_ptr 中。该对象通过 python 内部的 python 绑定进行访问,并传递给另一个试图保持它的绑定 C++ 函数。似乎当对象从 C++ 转到 Python 时,它从 shared_ptr 转换为 python 对象。然后当它返回 C++ 时,它会从 python 对象转换为新的 shared_ptr,但是这个 shared_ptr 与初始持有的 shared_ptr 无关。

是否可以设置 boost-python 绑定,以便从 python 对象到 shared_ptr 的转换引用原始 shared_ptr 内部?

下面是我用来显示问题的节略代码。

在此示例中,对象最初保存在名为 s_inital 的 shared_ptr 中。它通过 getSharedPtr 函数从 python 中获取,然后通过 putSharedPtr 函数推回 C++。在 putSharedPtr 中,它被复制到weak_ptr s_copied 中。检查调试器中的指针显示 putSharedPtr 中使用的 shared_ptr 与 s_initial 没有相同的引用计数内部。最后的断言将触发,因为弱指针 s_copied 仅与单个强指针(在 putSharedPtr 中使用的指针)相关,并且一旦 putSharedPtr 完成,该指针就被破坏了。

static shared_ptr<Captured> s_initial;
static weak_ptr<Captured> s_copied;

class UseSharedPtr
{
public:
    shared_ptr<Captured> getSharedPtr()
    {
        return s_initial;
    }

    void putSharedPtr(shared_ptr<Captured> ptr)
    {
        s_copied = ptr;
    }
};


BOOST_PYTHON_MODULE(test)
{
    class_<Captured, shared_ptr<Captured>, boost::noncopyable>("Captured", no_init);
    class_<UseSharedPtr, boost::noncopyable>("UseSharedPtr", init<>())
        .def("getSharedPtr", &UseSharedPtr::getSharedPtr)
        .def("putSharedPtr", &UseSharedPtr::putSharedPtr)
    ;
}



    s_initial = make_shared<Captured>();

    const char* chunk = "\
from test import UseSharedPtr \n\
x = UseSharedPtr() \n\
ptr = x.getSharedPtr() \n\
x.putSharedPtr(ptr)\n\
del x \n\
del ptr \n\
";
    object result = exec(chunk, mainNamespace, mainNamespace);

    assert(s_copied.lock());

【问题讨论】:

  • 整个UseSharedPtr类的目的是什么?就像Captured 现在公开一样,boost::python 会正确处理。
  • 我认为这只是一个例子。虽然 boost.python 将正确调用共享类的方法,但它在将 shared_ptr 作为参数传递给其他类时存在问题。

标签: boost shared-ptr boost-python


【解决方案1】:

您需要class_&lt;UseSharedPtr, shared_ptr&lt;UseSharedPtr&gt;, boost::noncopyable&gt; 以便 boost::python 知道它应该使用 shared_ptr 管理对象。如果您希望我验证,请让您的示例可编译。

【讨论】:

  • shared_ptrnoncopyable 标志已经出现在发布的示例中。
【解决方案2】:

一个简单但丑陋的解决方法是将enable_shared_from_this() 用于Captured 类,并使用shared_from_this() 为每个参数获取一个新的shared_ptr

void putSharedPtr(shared_ptr<Captured> ptr)
{
    s_copied = ptr->shared_from_this();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    相关资源
    最近更新 更多