Я пытаюсь выставить свои классы С++ на Python с помощью Boost.Python. Вот простая версия того, что я пытаюсь сделать:
У меня есть класс A, полученный из boost:: noncopyable и второго класса B с помощью метода, который ссылается на A как на аргумент.
class A : boost::noncopyable { /*...*/ };
class B {
public:
virtual void do_something(A& a) {
/*...*/
}
};
Я подвергаю классы следующим образом:
/* 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)
копируется во время вызова функции, даже если он передается по ссылке. Но просто удалить ненужное требование на A
не является вариантом, так как он там по какой-то причине.
Любые предложения по решению проблемы?
Спасибо.