Skip to content

Passing function pointers to C functions #40

@angainor

Description

@angainor

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions