es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo configurar una función de Python como callback para C++ utilizando pybind11?

typedef bool (*ftype_callback)(ClientInterface* client, const Member* member, int member_num);

struct Member {
    char x[64];
    int y;
};

class ClientInterface {
public: 
    virtual int calc() = 0;
    virtual bool join() = 0;
    virtual bool set_callback(ftype_callback on_member_join) = 0;
};

Es un SDK desde el cual puedo llamar al cliente desde una biblioteca dinámica en los códigos de C++.

bool cb(ClientInterface* client, const Member* member, int member_num) {
    // hacer algo
}
cli->set_callback(cb);
cli->join();

Quiero portarlo a enlaces en Python usando pybind11. ¿Cómo puedo establecer el callback en Python?

He consultado la documentación y he intentado:

PYBIND11_MODULE(xxx, m) {
    m.def("set_callback", [](xxx& self, py::function cb) {
        self.set_callback(cb);
    });
}

El código simplemente no compila.

Mi pregunta es, ¿cómo puedo convertir py::function a ftype_callback o hay otra manera de hacerlo?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para convertir py::function a ftype_callback en pybind11, puedes usar py::cpp_function::make() para envolver la función de callback de Python y luego convertirla al puntero de función esperado. Aquí tienes un ejemplo de implementación de la función set_callback:

    “`c++
    #include #include #include “your_sdk_header.h” // reemplazar con el encabezado real del SDK

    namespace py = pybind11;

    PYBIND11_MODULE(example, m) {
    py::class_(m, “ClientInterface”)
    .def(“calc”, &ClientInterface::calc)
    .def(“join”, &ClientInterface::join)
    .def(“set_callback”, [](ClientInterface &self, py::function cb) {
    ftype_callback cb_c = reinterpret_cast(
    py::cpp_function(cb).cast<void*>());
    self.set_callback(cb_c);
    });
    }
    “`

    py::cpp_function(cb) crea un objeto de función con tipo borrado que se puede convertir a void*, el cual se convierte al tipo de puntero de función esperado ftype_callback utilizando reinterpret_cast. Ten en cuenta que esto solo es seguro si la función de callback de Python tiene una firma compatible, es decir, toma parámetros ClientInterface*, const Member* e int y devuelve un bool.

    Con esta implementación, puedes pasar una función de Python como argumento de callback:

    “`python
    import example

    def cb(cliente, miembro, num_miembro):
    # hacer algo
    return True

    cli = example.ClientInterface()
    cli.set_callback(cb)
    cli.join()
    “`</void*>

Comments are closed.