Boost.Python和C++的std::vector指针

6

我正在使用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()是纯虚函数,而第二行则打印出:

Derived::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*?我该怎么做才能让它工作呢?
1个回答

3
您可以通过注册Base*作为指向BaseWrapper*的类型来解决此问题:
class_<BaseWrapper, noncopyable, Base*>("Base")
        .def("func", pure_virtual(&Base::func));

但是看起来这意味着Base不能有一个纯虚函数...


是的,将Base::func() 改为非纯虚函数可以解决问题。谢谢,至少对于这个解决方案。但是是否有一些解决方法不会改变任何现有的API呢? - Ivan Nikolaev
然而,仅仅使其不纯并不能解决问题,还需要将Base*注册为指向BaseWrapper的指针类型,除非我弄错了?也许有一种方法可以强制boost python接受具有纯虚拟方法的类型作为指针类型... - James
是的,我的意思是使 func() 不纯,并注册 Base* 指针解决了问题。你能更好地解释一下如何让Python接受具有纯虚函数的类型吗? - Ivan Nikolaev
这是由boost python拒绝的。我认为开始的地方应该是查看编译器错误消息,如果您将Base*声明为BaseWrapper的指针类型,并将函数保留为纯虚函数。 - James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接