Tengo una función de biblioteca C que espera un argumento char const **, como:

void set_values(void* object, char const ** values, int dim1, int dim2);

Donde values es una matriz de dim1*dim2 longitud que apunta a valores de cadena terminados en nulo.

Cuando intento llamar a esta función usando cffi / ctypes, el siguiente código de Python produce un error:

LP_c_char  = ctypes.POINTER(ctypes.c_char)

dim1 = 2
dim2 = 3
values = ('1.0', '2.0', '1.2', '2.2', '1.5', '2.5')

values_ptr = (LP_c_char * (dim1 * dim2))()
for i, value in enumerate(values):
    values_ptr[i] = ctypes.create_string_buffer(value.encode('utf-8'))

mylib.set_values(object, values_ptr, dim1, dim2)

El resultado es el siguiente error en la línea mylib.set_values(...):

TypeError: initializer for ctype 'char * *' must be a cdata pointer, not LP_c_char_Array_6

Lamentablemente, values no puede ser una matriz double* porque la biblioteca acepta nombres y expresiones de variables.

Estaba siguiendo este viejo hilo. Estoy usando Python 3.7.2 y cffi 1.14.0.

¿Alguien puede señalar lo que estoy haciendo mal aquí?

0
David 24 jun. 2020 a las 15:12

2 respuestas

La mejor respuesta

No puedes mezclar ctypes y cffi así. Son dos proyectos diferentes. En este caso, está intentando llamar a una función expuesta por cffi pero pasando argumentos que son objetos ctypes. Intente construir objetos cffi en su lugar, p. con ffi.new().

1
Armin Rigo 24 jun. 2020 a las 14:34

Siguiendo el consejo de respuesta aceptado, encontré un ejemplo en la documentación de cffi que resolvió el problema. Compartir con quien sea podría tener la misma pregunta.

dim1 = 2
dim2 = 3
values = ('1.0', '2.0', '1.2', '2.2', '1.5', '2.5')

values_ptr = [ffi.new("char[]", bytes(value, encoding="utf-8")) for value in values]

mylib.set_values(object, ffi.new("char *[]", values_ptr), dim1, dim2)
0
David 24 jun. 2020 a las 23:17