Como faço para usar ctypes para definir ponteiro de função externa de uma biblioteca para uma função de retorno de chamada Python?

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

  •  20-08-2019
  •  | 
  •  

Pergunta

Alguns ponteiros de função bibliotecas C exportação de tal forma que o usuário dos conjuntos de biblioteca que função ponteiro para o endereço de sua própria função para implementar um gancho ou de retorno de chamada.

Neste biblioteca exemplo liblibrary.so, como faço para definir library_hook para uma função Python usando ctypes?

library.h:

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

Solução

Isto é complicado em ctypes porque ctypes funcionar ponteiros não implementar a propriedade .value usado para definir outros ponteiros. Em vez disso, lançar sua função de retorno e o ponteiro de função externo para void * com a função c_void_p. Depois de definir o ponteiro de função como void * como mostrado, C pode chamar sua função Python, e você pode recuperar a função como um ponteiro de função e chamá-lo com chamadas ctypes normais.

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top