某些C库导出函数指针,以便库的用户将该函数指针设置为自己函数的地址,以实现钩子或回调。
在这个示例库liblibrary.so
中,如何使用ctypes将library_hook设置为Python函数?
library.h:
typedef int exported_function_t(char**, int);
extern exported_function_t *library_hook;
答案 0 :(得分:9)
这在ctypes中很棘手,因为ctypes函数指针不实现用于设置其他指针的.value
属性。相反,使用void *
函数将回调函数和extern函数指针强制转换为c_void_p
。在将函数指针设置为void *
之后,如图所示,C可以调用Python函数,并且可以将函数作为函数指针检索并使用正常的ctypes调用来调用它。
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