In order to pass a C/C++ function pointer to a Python function you need to convert it into a Python object (since all arguments to Python functions must be Python objects). You can create a DIY version with an outline something like this:
typedef struct {
PyObject_HEAD
int (*ptr)(int, int); // assuming this matches the signature of the function pointer
} MyFuncPtr;
PyObject* Call_MyFuncPtr(MyFuncPtr* self, PyObject* args, PyObject* kwargs) {
// implementation goes here...
// you probably want to convert the Python arguments to C with PyArg_ParseTupleAndKeywords
// call the function
// then convert the C return value back to a PyObject* and return that
}
The associated PyTypeObject
is defined pretty as in the tutorial - the only change you need to make is to set tp_call
to Call_MyFuncPtr
so that the type is callable in Python (you may need a cast here - the signatures don't quite match because of the type of the first argument). You don't need to add it to a module object (since it'll only be accessible from C anyway) but you do need to call PyType_Ready
on it.
You'd then allocate it using
MyFuncPtr* mfp = PyObject_New(MyFuncPtr,&MyFuncPtr_Type)
mfp->ptr = // some matching C/C++ function
and pass it is an argument to Python using a standard C API function call.
It's possible that there you want to avoid doing this yourself and use an existing library. For C++, Boost Python defines a nice wrapper that automatically does this, as does PyBind11. You might also be able to use the Ctypes or CFFI libraries, but it isn't immediately obvious to me how you interface with them from C or C++.