I'm currently porting a C library to python using pybind11, and it has lots of C-style function pointers (i.e. not std::function, as described in https://pybind11.readthedocs.io/en/stable/advanced/cast/functional.html)
So my question is: is there an easy way to handle C style function pointers, when they are passed a function parameters?
For example I need to bind this function type (as an illustration, I took function pointers from the C library glfw)
typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event);
which is used like this:
void glfwSetMonitorCallback(GLFWmonitorfun cbfun)
I know I could wrap the function pointers in std::function, but it is quite cumbersome, since there are about 30 different function pointer types in the library, and I would need to patch manually all their usages.
Is there an easier way ?
PS: Below is how I could wrap them with std::function. Beware, this is borderline atrocious, since it requires global variable and global callbacks. This is exactly what I would like to avoid.
// C function pointer type
typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event);
// Wrapper std::function type
using GLFWmonitorfun_std = std::function<void(GLFWmonitor*, int)>;
// We need to store a global std::function pointer
GLFWmonitorfun_std globalGLFWmonitorfun_std;
// As well as a global C callback
void myGlobalCallback(GLFWmonitor* monitor, int event)
{
if (globalGLFWmonitorfun_std)
globalGLFWmonitorfun_std(monitor, event);
}
void py_init_module_glfw(py::module& m)
{
m.def("glfwSetMonitorCallback", [](const GLFWmonitorfun_std& f) {
// And we set the global std::function pointer in the binding
globalGLFWmonitorfun_std = f;
// Before setting the C callback
glfwSetMonitorCallback(myGlobalCallback);
});
// ....