【问题标题】:Using Boost Python with shared_ptr<const T>将 Boost Python 与 shared_ptr<const T> 一起使用
【发布时间】:2018-05-13 05:33:44
【问题描述】:

Boost Python 1.63 (python 2.7.13) 与shared_ptr&lt;T&gt; 配合得很好;如果我用 C++ 编写:

shared_ptr<Foo> create_shared_ptr() { return shared_ptr{...}; }
void accept_shared_ptr(const shared_ptr<Foo>& p) { }

...

class_<Foo, boost::noncopyable>("Foo", no_init); //Expose abstract class

register_ptr_to_python< shared_ptr<Foo> >();
def("create_shared_ptr", create_shared_ptr);
def("accept_shared_ptr", accept_shared_ptr);

然后我可以用 Python 编写这个并且一切正常:

accept_shared_ptr(create_shared_ptr())

当我尝试包装 shared_ptr&lt;const Foo&gt; 时,问题就来了。(我需要这样做,因为我正在包装一个返回它的库。)如果我如下修改 C++ 函数: p>

shared_ptr<const Foo> create_shared_ptr() { return shared_ptr{...}; }
void accept_shared_ptr(const shared_ptr<const Foo>& p) { }

然后我得到错误:

Boost.Python.ArgumentError: Python argument types in
    mod_python.accept_shared_ptr(Foo)
did not match C++ signature:
    accept_shared_ptr(std::shared_ptr<Foo const>)

内部似乎正在实现从 python Foo 到 C++ shared_ptr&lt;Foo&gt; 的转换,而不是到 C++ shared_ptr&lt;const Foo&gt; 的转换。使用

register_ptr_to_python< shared_ptr<const Foo> >();

没有帮助。我该如何解决这个问题?

【问题讨论】:

  • 致投票结束的人:以下基于 boost 1.62 的答案并不能解决问题。 2016 年 9 月 23 日有一个提交 Add support for std::shared_ptr.。Boost 1.62 于 9 月 1 日发布,1.62 于 11 月 2 日发布。(github.com/boostorg/python/commit/…)。这个提交有可能破坏了一些东西。
  • 请包含命名空间,不清楚您使用的是 std::shared_ptr 还是 boost_shared_ptr

标签: python c++ boost constants shared-ptr


【解决方案1】:

问题必须在您的类/方法的定义中。这段代码对我有用(我有 boost 1.62 和 python 2.7.13):

class Foo {
public:
    virtual ~Foo() = default;
    virtual std::string xxx() = 0;
};

class Bar: public Foo {
public:
    ~Bar() override = default;
    std::string xxx() override { return "xxx"; }
};

std::shared_ptr<const Foo> create_shared_ptr() {
    return std::shared_ptr<const Foo>(new Bar);
}

void accept_shared_ptr(const std::shared_ptr<const Foo>& p) 
{
    ; // do nothing
}

BOOST_PYTHON_MODULE(myLib)
{
    using namespace boost::python;
    class_<Foo, boost::noncopyable>("Foo", no_init);
    register_ptr_to_python< std::shared_ptr<const Foo> >();
    def("create_shared_ptr", create_shared_ptr);
    def("accept_shared_ptr", accept_shared_ptr);
}

然后,在 python 中我可以这样做:

$ python
Python 2.7.13 (default, Jan 19 2017, 14:48:08) 
[GCC 6.3.0 20170118] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import myLib
>>> ptr = myLib.create_shared_ptr()
>>> ptr
<myLib.Foo object at 0x7f8b5fde0aa0>
>>> myLib.accept_shared_ptr(ptr)

很可能你的函数create_shared_ptr 以某种方式返回了一个被python误解的错误值。

【讨论】:

  • 有趣。您的 C++ 代码为我生成了相同的错误:Python argument types in myLib.accept_shared_ptr(Foo) did not match C++ signature: accept_shared_ptr(std::shared_ptr&lt;Foo const&gt;)
  • 请问您使用的是什么编译器?我正在使用 g++ 6.4 并使用 -std=c++11 进行编译。您是否还包括任何可能允许更多转换的标题?
  • g++ (Debian 6.3.0-18) 6.3.0 20170516-std=c++1y(我知道,应该是c++14),cmake version 3.7.2。从 boost 中只包含 #include &lt;boost/python.hpp&gt;,但实际上我将示例代码嵌入到我的另一个项目中,其中包含 OpenCV 依赖项。我看到问题已经解决了 - 很好(即使可能有点 hacky)。
【解决方案2】:

添加

implicitly_convertible<std::shared_ptr<Foo>,std::shared_ptr<const Foo>>();

解决问题。

【讨论】:

    猜你喜欢
    • 2018-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    相关资源
    最近更新 更多