【问题标题】:Boost.Python and C++ std::vector of pointersBoost.Python 和 C++ std::vector 指针
【发布时间】:2011-11-17 09:23:38
【问题描述】:

我正在使用 Boost.Python 为我的 C++ 库创建一个包装器,但我遇到了一些麻烦,整天搜索谷歌并没有产生任何结果。例如,我有以下代码:

class Base
{
public:
    virtual void func() = 0;
};

class Derived : public Base
{
public:
    virtual void func()
    {
        cout << "Derived::func()"<< endl;
    }
};


// wrapper for Base
struct BaseWrapper : Base, python::wrapper<Base>
{
    virtual void func()
    {
        this->get_override("func");
    }
};


Base* makeDerived()
{
    return new Derived;
}

vector<Base*>* makeDerivedVec()
{
    vector<Base*> *v = new vector<Base*>;
    v->push_back(new Derived);
    v->push_back(new Derived);
    v->push_back(new Derived);
    return v;
}

BOOST_PYTHON_MODULE(mylib)
{
    // export Base
    class_<BaseWrapper, noncopyable>("Base")
            .def("func", pure_virtual(&Base::func));

    class_<vector<Base*> >("BasePtrVec")
            .def(vector_indexing_suite<vector<Base*> >());

    // export Derived
    class_<Derived, bases<Base> >("Derived")
            .def("func", &Derived::func);

    // export makeDerived()
    def("makeDerived", &makeDerived, return_value_policy<manage_new_object>());

    // export makeDerivedVec()
    def("makeDerivedVec", &makeDerivedVec, return_value_policy<manage_new_object>());
}

所以,我编译它,在 python 中导入并试试这个:

b = mylib.Base() b.func()

d = mylib.makeDerived() d.func()

如预期的那样,第一行抛出一个异常,说 b.func() 是纯虚拟的,第二行打印出来

派生的::func()

没关系。

但是代码

dlist = mylib.makeDerivedVec()
for d in dlist:
    d.func()

不起作用,Python抛出异常:

TypeError: No to_python (by-value) converter found for C++ type: Base*

为什么它正确处理了 makeDerived() 返回的 Base* 并拒绝使用 std::vector 中包含的 Base*?我怎样才能让它工作?

【问题讨论】:

    标签: python pointers boost vector


    【解决方案1】:

    您可以通过将Base* 注册为可用于指向BaseWrapper* 的类型来解决此问题:

    class_<BaseWrapper, noncopyable, Base*>("Base")
            .def("func", pure_virtual(&Base::func));
    

    但是好像这意味着Base不能有纯虚函数……

    【讨论】:

    • 是的,使 Base::func() 不纯可以解决问题。谢谢,至少对于这个解决方案。但是是否有一些不改变任何现有 API 的解决方法?
    • 解决问题的方法不仅仅是让它不纯,它还将Base*注册为BaseWrapper的指针类型,除非我弄错了?也许有一种方法可以强制 boost python 接受具有纯虚方法的类型作为指针类型...
    • 是的,我的意思是让 func() 不纯,注册 Base* ptr 解决了这个问题。你能更好地解释一下如何让 python 接受纯虚拟的类型吗?
    • 是 boost python 拒绝了它。我认为开始的地方是查看编译器错误消息,如果您将Base* 声明为BaseWrapper 的指针类型,并将函数保留为纯虚拟函数。
    猜你喜欢
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 2021-04-08
    • 2010-10-27
    相关资源
    最近更新 更多