I am trying to write a wrapper around a C program so that I can call it from Python. I am using Cython to do this. The C function takes a callback function as an argument, but this call back function will only be known at run-time of the python program. I have been searching how to do this and it seems there is not simple solution but the following seems to work:
#python.py
libc = cdll.LoadLibrary("myfunc.so") #Callback function is defined in myfunc.so
....
c_wrapper(libc.fun, ...)
.
#c_wrapper.pyx
cdef extern void mainfunction(void *F, ...) #The intial C function we are wrapping
ctypedef void (*myfuncptr) ()
def c_wrapper(f, ...) # our function pointer is passed to the wrapper as a Python object
cdef myfuncptr thisfunc
thisfunc = (<myfuncptr*><size_t>addressof(f))[0]
mainfunction(thisfunc, ...)
This method works for C and FORTRAN functions (i am assuming it will work for most compiled languges) and Python functions (using C types), but it seems a little awkward. Is there any more simple way of doing this in Cython?
Thanks
EDIT : I am unable to change the C library I am trying to wrap
I guess you’re aware of this?So, knowing that you can dload your main function, let’s take another approach. I wrote a couple of stupid functions to test this:
then, the function that takes the callback
Which can be passed directly from Python:
And now, let’s wrap a Python function: