Вызов Boost.Python по ссылке: TypeError: Для типа C ++ не найден преобразователь to_python (по значению):

Я пытаюсь предоставить свои классы C ++ для Python, используя Boost.Python. Вот упрощенная версия того, что я пытаюсь сделать:

У меня есть класс A, производный от boost :: noncopyable, и второй класс B с методом, который принимает ссылку на A в качестве аргумента.

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

class B {

public:

    virtual void do_something(A& a) {
        /*...*/
    }
};

I Я раскрываю классы следующим образом:

/* 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)
    ;
}

Я расширяю B в python следующим образом:

test.py:

import SomeModule


class BDerived(SomeModule.B):

    def do_something(self, a):
        pass

и вызываю расширенный 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();
}

Однако это приводит к сообщению об ошибке:

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

Если A не является производным от boost :: noncopyable , код выполняется без ошибок, но аргумент a в do_something (A & a) копируется во время вызов функции, даже если это ' s передано по ссылке. Но просто удалить требование отсутствия копирования на A не вариант, так как оно существует по какой-то причине.

Есть предложения, как решить проблему?

Спасибо.

20
задан Kai 17 March 2011 в 09:07
поделиться