Comment utiliser ctypes pour définir le pointeur de fonction externe d'une bibliothèque sur une fonction de rappel Python?

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

  •  20-08-2019
  •  | 
  •  

Question

Certaines bibliothèques C exportent les pointeurs de fonction de telle sorte que l'utilisateur de la bibliothèque le place à l'adresse de sa propre fonction pour implémenter un raccordement ou un rappel.

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;
Était-ce utile?

La solution

Ceci est délicat dans ctypes car les pointeurs de fonction ctypes n’implémentent pas la propriété .value utilisée pour définir d’autres pointeurs. A la place, transformez votre fonction de rappel et le pointeur de la fonction externe sur void * avec la fonction c_void_p. Après avoir défini le pointeur de fonction sur <=> comme indiqué, C peut appeler votre fonction Python. Vous pouvez alors 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top