Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use ctypes to set a library's extern function pointer to a Python callback function?

Tags:

python

ctypes

Some C libraries export function pointers such that the user of the library sets that function pointer to the address of their own function to implement a hook or callback.

In this example library liblibrary.so, how do I set library_hook to a Python function using ctypes?

library.h:

typedef int exported_function_t(char**, int);
extern exported_function_t *library_hook;
like image 924
joeforker Avatar asked Sep 01 '26 21:09

joeforker


1 Answers

This is tricky in ctypes because ctypes function pointers do not implement the .value property used to set other pointers. Instead, cast your callback function and the extern function pointer to void * with the c_void_p function. After setting the function pointer as void * as shown, C can call your Python function, and you can retrieve the function as a function pointer and call it with normal ctypes calls.

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
like image 84
joeforker Avatar answered Sep 03 '26 11:09

joeforker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!