Estoy tratando de exponer mis clases de C++ a Python usando Boost.Python. Aquí hay una versión simplificada de lo que estoy tratando de hacer:Boost.Python llamada por referencia: TypeError: No to_python (by-value) converter found for C++ type:
Tengo una clase A derivada de boost :: noncopyable y una segunda clase B con un método que toma como referencia una A como argumento.
class A : boost::noncopyable { /*...*/ };
class B {
public:
virtual void do_something(A& a) {
/*...*/
}
};
estoy exponiendo las clases de la siguiente manera:
/* 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)
;
}
que se extienden B en Python como esto:
test.py:
import SomeModule
class BDerived(SomeModule.B):
def do_something(self, a):
pass
y llame a la extendida B como este:
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();
}
Sin embargo, esto da como resultado un mensaje de error:
TypeError: No to_python (by-value) converter found for C++ type: A
Si A
no se deriva de boost::noncopyable
el código se ejecuta sin ningún error pero el argumento a en do_something(A& a)
se copia durante la llamada a la función a pesar de que se aprobó en por referencia. Pero simplemente eliminar el requisito no copiable en A
no es una opción, ya que está ahí por una razón.
¿Alguna sugerencia sobre cómo solucionar el problema?
Gracias.
Para las personas que desembarquen aquí: hay un error reciente en Boost 1.60.0 que se parece mucho a esto, se debe solucionar en Boost 1.61.0, ver también https://github.com/boostorg/python/pull/59 –
@KennethHoste ¡MUCHAS GRACIAS! me salvaste de varios días más si no semanas de error! tan feliz que encontré este pequeño comentario !! :) – Mangostaniko