C++类和Python对象

3

我有两个抽象的C++类,我在Python中暴露并派生它们。我试图在C++中提取那些派生对象,并调用一个类的某个方法,将另一个类的实例传递给第一个类。这些类被定义如下:

struct A {
    std::vector<int> numbers;

    virtual void a() = 0;
};

struct B {
    virtual void b(const A& a) = 0;
};

我使用 boost::python 将它们暴露给Python。

namespace py = boost::python;

struct A_wrapper : A, py:wrapper<A> {
    void a() {
        this->getoverride("a")();
    }
};

struct B_wrapper : B, py::wrapper<B> {
    void b(const A& a) {
        this->get_override("b")(a);
    }
};

BOOST_PYTHON_MODULE(example) {
    typedef std::vector<int> int_vec_t;

    py::class_<int_vec_t>("IntList")
        .def(py::vector_indexing_suite<int_vec_t>());

    py::class_<A_wrapper, boost::noncopyable>("A")
        .def_readwrite("numbers", &A::numbers)
        .def("a", py::pure_virtual(&A::a));

    py::class_<B_wrapper, boost::noncopyable>("B")
        .def("b", py::pure_virtual(&B::b));
}

我的Python类只是将数字数组填充为随机数,B::b 用于调试目的打印这些数字。
我可以导入它们并提取这两个类到boost::shared_ptr中,没有问题。它们初始化程序中的任何Python代码甚至也被调用了。
auto pyA = py::extract<boost::shared_ptr<A> >(/*py object containing derivation of A*/)();
auto pyB = py::extract<boost::shared_ptr<B> >(/*py object containing derivation of B*/)();

但是当我尝试调用 pyB->b(*pyA) 时,会出现以下错误:

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

我做错了什么?我如何使用一个A的实例调用Python对B::b的派生?
1个回答

1
问题在于必须将抽象类声明为boost::noncopyable。正如文档所述:

boost::noncopyable[sic] 抑制自动注册将T实例复制的to_python转换。当T没有公共可访问的复制构造函数时需要。

因此,我们可以将python对象转换为C++实例,但反之不行,这导致了在尝试执行此操作时出现的错误。
解决方案实际上在问题的答案评论中。
wrapper类中,通过引用传递对象而不是按值传递;因此,该类不必转换为python。这样留下的包装器看起来像这样:
struct B_wrapper : B, py::wrapper<B> {
    void b(const A& a) {
        this->get_override("b")(boost:ref(a));
    }
};

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