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

6 投票
1 回答
831 浏览
提问于 2025-04-17 06:29

我正在使用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 不能有一个纯虚函数...

撰写回答