I am trying to call a C-function from Python that takes a function pointer as parameter. I need that function to be dynamically determined at runtime. Using ctypes
, that is pretty simple.
The C-code could look like this:
// my_c_funcs.h
double mul(double, double);
double add(double, double);
double do_something(double (*)(double, double), double, double);
// my_c_funcs.h
int mul(int a, int b) {
return a*b;
}
int add(int a, int b) {
return a + b;
}
int do_something(int (*f)(int, int), int a, int b) {
return f(a, b);
}
Having compiled that code into a shared library named "libMyCFuncs.so", I can pass a function that is determined at runtime in Python using ctypes
:
# foo.py
import ctypes
lib = ctypes.cdll.LoadLibrary("./libMyCfuncs.so")
def foo(func_name, a, b):
func = getattr(lib, func_name)
return lib.do_something(func, a, b)
I know I should define the return types but I left that out for brevity and used int
s only.
The code above gives the expected result, e.g. calling foo.foo('add', 2, 4)
yields 6
. However, I'd prefer using Cython because I make a lot of use of two- or higher-dimensional arrays and passing arrays is IMHO a lot easier in Cython. Let's say the Cython code is in "foo.pyx":
# foo.pyx
cdef extern from "my_c_funcs.h":
int mul(int, int)
int add(int, int)
int do_something(int (*)(int, int), int, int)
def foo(func_name, int a, int b):
# ???
Calling getattr
or even eval
obviously doesn't work. So how can I realize that in Cython?