使用Boost Python和shared_ptr <const t =“”>

时间:2017-11-29 13:26:42

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

Boost Python 1.63(python 2.7.13)适用于shared_ptr<T>;如果我用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<const Foo>时会出现问题。(我需要这样做,因为我正在包装一个返回它的库。)如果我修改C ++函数如下:

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<Foo>的转换,但没有实现到C ++ shared_ptr<const Foo>的转换。使用

register_ptr_to_python< shared_ptr<const Foo> >();

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

2 个答案:

答案 0 :(得分:1)

问题必须出在您的类/方法的定义中。这段代码适合我(我有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误解的错误值。

答案 1 :(得分:1)

添加

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

解决了这个问题。