He estado trabajando con Cython en un intento de interactuar con una biblioteca escrita en C++. Hasta ahora las cosas están yendo bastante bien, y puedo usar efectivamente las funciones de MOST dentro de la biblioteca. Mi único problema radica en implementar callbacks. La biblioteca cuenta con 4 definiciones de funciones que se ven un poco algo como esto:Cython: implementar devoluciones de llamada
typedef void (*Function1)(const uint16_t *data,
unsigned width, unsigned height);
void SetCallBack(Function1);
que las apliquen pensé que podría hacer algo como esto con Cython:
ctypedef void (*Function1)(unsigned short *data,
unsigned width, unsigned height);
cdef extern from "lib.hpp":
void SetCallBack(Function1)
Que en realidad se compila correctamente, sin embargo, No puedo, por mi propia vida, pensar cómo implementarlo de tal manera que la devolución de llamada funcione. La primera vez que intenté crear una función que acaba de llamar a que, de forma similar a la forma en que lo haría para cualquier otra función, empezar con esto:
def PySetCallBack(Func):
SetCallBack(Func)
pero eso me da la (predecible) Error:
"No se puede convertir el objeto de Python a 'Function1'"
así que sí, ahí es donde estoy. Si alguien tiene experiencia en configurar devoluciones de llamadas en Cython, le agradecería cualquier ayuda. Gracias.
Editar: Siguiendo su consejo, he creado una función intermedia con un cdef, que se ve así:
cdef void cSetCallBack(Function1 function):
SetCallBack(function)
Esto me parece haber conseguido ... Más cerca? Conseguir un error diferente ahora por lo menos:
error: invalid conversion from ‘void (*)(short unsigned int*, unsigned int, unsigned int)’ to ‘void (*)(const uint16_t*, unsigned int, unsigned int)’
Ahora, lo que puedo decir a esos tipos son idénticos, por lo que no puedo entender lo que está pasando.
Edit2: Corregido el problema al declarar un nuevo typedef:
ctypedef unsigned short uint16_t
y usar eso como argumento para llamar, pero al parecer eso no era en realidad para llegar más cerca, pero sólo teniendo a mi alrededor una pista lateral, ya que cuando intento llamar a esa función, obtengo el mismo error "No se puede convertir el objeto Python en 'Función1'" de nuevo.
Por lo tanto, estoy más o menos donde comencé. Lo único que puedo hacer ahora es convertir explícitamente el objeto python en una función c como esa, pero, para ser sincero, no tengo idea de cómo lo haría.
Editar la tercera: bien, después de la disección de su respuesta que finalmente lo consigue, y funciona, por lo hurra y otras cosas. Lo que terminé haciendo fue la creación de una función como esta:
cdef void cSetCallback(Function1 function):
SetCallback(function)
cdef void callcallback(const_ushort *data, unsigned width, unsigned height):
global callbackfunc
callbackfunc(data,width,height)
cSetCallback(callcallback)
def PySetCallback(callbackFunc):
global callbackfunc
callbackfunc = callbackFunc
Así que ahora el único problema es que no puede convertir const_ushort * datos en un objeto de Python, pero ese es otro problema por completo, así que supongo que éste está resuelto, muchas gracias.
Cambiar 'short unsigned int *' a 'const short unsigned int *'. – aschepler
Según mi leal saber y entender, Cython no tiene idea de qué significa const, y cada vez que intento usarlo, obtengo "Const no es un identificador de tipo". – Josiah