2009-01-29 6 views
3

Certaines bibliothèques C exportent des pointeurs de fonction de sorte que l'utilisateur de la bibliothèque place ce pointeur de fonction sur l'adresse de sa propre fonction pour implémenter un hook ou un callback.Comment utiliser ctypes pour définir le pointeur de fonction externe d'une bibliothèque sur une fonction de rappel Python?

Dans cet exemple de bibliothèque liblibrary.so, comment définir library_hook sur une fonction Python à l'aide de ctypes?

library.h:

typedef int exported_function_t(char**, int); 
extern exported_function_t *library_hook; 

Répondre

9

Ceci est difficile à ctypes parce que les pointeurs de fonction ctypes ne mettent pas en œuvre la propriété .value utilisé pour définir d'autres pointeurs. À la place, lancez votre fonction de rappel et le pointeur de fonction externe sur void * avec la fonction c_void_p. Après avoir défini le pointeur de fonction sur void * comme indiqué, C peut appeler votre fonction Python et vous pouvez récupérer la fonction en tant que pointeur de fonction et l'appeler avec des appels ctypes normaux.

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 
Questions connexes