通过引用调用Boost.Python:TypeError:找不到C++类型的to_python(by-value)转换器:

Kai*_*Kai 20 c++ python boost boost-python

我正在尝试使用Boost.Python将我的C++类公开给Python.这是我正在尝试做的简化版本:

我有一个派生自boost :: noncopyable的类A和一个带有一个方法的类B,该方法将A作为参数引用.

class A : boost::noncopyable { /*...*/ };

class B {

public:

    virtual void do_something(A& a) {
        /*...*/
    }
};
Run Code Online (Sandbox Code Playgroud)

我正在公开课程如下:

/* Wrapper for B, so B can be extended in python */
struct BWrap : public B, wrapper<B> {

    void do_something(A &a) {

        if (override do_something = this->get_override("do_something")) {
            do_something(a);
            return;
        }
        else {
            B::do_something(a);
        }
    }

    void default_do_something(A& a) { this->B::do_something(a); }
};

BOOST_PYTHON_MODULE(SomeModule) {

    class_<A, boost::noncopyable>("A");

    class_<BWrap, boost::noncopyable>("B")
        .def("do_something", &B::do_something, &BWrap::default_do_something)
    ;
}
Run Code Online (Sandbox Code Playgroud)

我像这样在python中扩展B:

test.py:

import SomeModule


class BDerived(SomeModule.B):

    def do_something(self, a):
        pass
Run Code Online (Sandbox Code Playgroud)

并像这样调用扩展B:

try {
    py::object main = py::import("__main__"); \
    py::object global(main.attr("__dict__")); \
    py::object result = py::exec_file("test.py", global, global); \
    py::object pluginClass = global["BDerived"]; \
    py::object plugin_base = pluginClass(); \

    B& plugin = py::extract<B&>(plugin_base) BOOST_EXTRACT_WORKAROUND;

    A a;
    B.do_something(a);
}
catch (py::error_already_set) { 
    PyErr_Print();
}
Run Code Online (Sandbox Code Playgroud)

但是,这会导致错误消息:

TypeError: No to_python (by-value) converter found for C++ type: A
Run Code Online (Sandbox Code Playgroud)

如果A不是从boost::noncopyable代码运行派生而没有任何错误,但参数a in do_something(A& a)在函数调用期间被复制,即使它是通过引用传入的.但只是删除A不可复制的要求不是一种选择,因为它是有原因的.

有什么建议如何解决问题?

谢谢.

小智 17

更改B.do_something(a);B.do_something(boost::ref(a));.

请参阅boost手册中的调用Python函数和方法.