¿Cómo uso ctypes para configurar el puntero de función externa de una biblioteca a una función de devolución de llamada de Python?

StackOverflow https://stackoverflow.com/questions/492377

  •  20-08-2019
  •  | 
  •  

Pregunta

Algunas bibliotecas C exportan punteros de función de modo que el usuario de la biblioteca establezca ese puntero de función en la dirección de su propia función para implementar un enlace o devolución de llamada.

En esta biblioteca de ejemplo liblibrary.so, ¿cómo configuro library_hook en una función de Python usando ctypes?

biblioteca.h:

typedef int exported_function_t(char**, int);
extern exported_function_t *library_hook;
¿Fue útil?

Solución

Esto es complicado en ctypes porque los punteros de función de ctypes no implementan la propiedad .value utilizada para establecer otros punteros. En su lugar, convierta su función de devolución de llamada y el puntero de la función externa a void * con la función c_void_p. Después de configurar el puntero de función como <=> como se muestra, C puede llamar a su función Python, y puede recuperar la función como puntero de función y llamarla con llamadas de tipo normal.

from ctypes import *

liblibrary = cdll.LoadLibrary('liblibrary.so')

def py_library_hook(strings, n):
    return 0

# First argument to CFUNCTYPE is the return type:
LIBRARY_HOOK_FUNC = CFUNCTYPE(c_int, POINTER(c_char_p), c_int)
hook = LIBRARY_HOOK_FUNC(py_library_Hook)
ptr = c_void_p.in_dll(liblibrary, 'library_hook')
ptr.value = cast(hook, c_void_p).value
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top