cpp_bindgen
cpp_bindgen copied to clipboard
Passing function pointers to C functions
In GHEX we need to pass a callback function from Fortran to the C++ library. The Fortran-C interface allows us to do this with the type(c_funptr)
type, e.g.:
[...]
interface
subroutine register_cb(cb) bind(c, name="register_cb")
use iso_c_binding
type(c_funptr), value :: cb
end subroutine register_cb
end interface
The problem is the lack of type checking on the Fortran side, i.e., the passed function pointer is never type-checked. A solution to this is to provide 1) a callback function interface definition and 2) a wrapper function, which takes the correctly typed function pointer and calls the underlying C interface, e.g.
interface
subroutine callback_t(rank, tag) bind(c)
integer(c_int), value :: rank, tag
end subroutine callback_t
subroutine register_cb_wrapped(cb) bind(c, name="register_cb")
use iso_c_binding
type(c_funptr), value :: cb
end subroutine register_cb_wrapped
end interface
contains
subroutine register_cb(cb)
use iso_c_binding
procedure(callback_t), pointer :: cb
call register_cb_wrapped(c_funloc(cb))
end subroutine register_cb
end
Notice that the use of a wrapper function here allows the user to pass fortran functions to the generated interface, so that he doesn't have to deal with the c_funloc
interface. It would of course be possible to live without the wrapper, but the above results in a cleaner native fortran code, where the user doesn't need to know that the backend is implemented in C.
In a sense, this is similar to the strong fortran side type checking described in #39, and could maybe be implemented in a similar fashion at least when it comes to the definition of the function type.