I have the following question. We have to pass callback functions to the C code. If the function is a Cython function in the same module, the situation is quite simple
In Cython:
def callme(int x):
c_callme(x, <int (*)(int)>&callbackme)
cdef int callbackme(int x):
print <int> x
return <int>x
In C:
int c_callme(int x, int (*f)(int))
{
printf("---%d\n",x);
printf("--%d\n",f(x));
return x;
}
The question is as follows: we want to generalize this code in the most Pythonic way so that it can accept also python functions as callback arguments (of course, some additional layer is needed), and also C/Cython functions from another module. I suppose, for C/Cython functions from a separate module one has to get the address of these functions (convert to long int?) and for Python function a certain wrapper is needed
I think the easiest way would be to wrap C callbacks in
so you can pass objects of this type, as well as any other callable, to the function that must call the callback.
However, if you must call the callback from C, then you should may pass it an extra argument, namely the optional address of a Python object, perhaps cast to `void*.
(Please do not cast function pointers to
long
, or you may get undefined behavior. I'm not sure if you can safely cast a function pointer to anything, evenvoid*
.)In this example, extracted from a Python wrapper to the Cubature integration C library, a Python function is passed to a C function that has the prototype given by
cfunction
. You can create a function with the same prototype, calledcfunction_cb
(callback), and returning the same type,int
in this example):When calling the C function, you can cast your callback wrapper using the C prototype:
In this example it is also shown how to pass arguments to your Python function, through C.