Automatic generation of a C header from Fortran code?

Dear Lazyweb,

In my newest project I need to use Fortran routines and variables in C. From the source code point of view this requires only to declare the needed Fortran entities in your C code whilst taking the “right” types of the variables and the name mangling of the Fortran compiler into account.

Here is an example. Consider you have the following Fortran code:

module X
  real, dimension(0:1) :: v
 
  subroutine Foo(A, b, c, &
    & D)
    integer, intent(in) :: a, &
      & B
    real, intent(out) :: C, d
    ! <Foo's body>
  end subroutine
end module X

To use the array v and the subroutine Foo() in C, you need to add (something like) the following declarations to your C source code:

extern float x_mp_v_[2];
 
void x_mp_foo_(int* a, int* b, float* c, float* d);

If only a handful of Fortran routines are needed to be called from C, declaring them by hand may be feasible. This is however error-prone and becomes impracticable for more than a handful of routines. Especially if the routine signatures change frequently.

So what I’d like to have is a tool that generates a C header file containing all declarations of Fortran entities from a given Fortran source file. Or if such tool does not exist, a tool that extracts variable declarations and routine signatures from a Fortran source file into a format that is easier to parse than Fortran itself would also be helpful. Any suggestions?

Tags: ,

4 Responses to “Automatic generation of a C header from Fortran code?”

  1. jldugger says:

    I don’t know of such a tool, but you can probably find an ANTLR grammar for fortran and write a quick program to process the AST for declarations. Just implement the right toString() functions and a decorator and you’re done!

  2. Alberto says:

    As you say, the problem has two parts:

    1. Name mangling, different between compilers.
    2. Writing the prototype.

    In order to solve the first, consider using the new ISO C bindings. Take a look from the page 31 in ftp://ftp.nag.co.uk/sc22wg5/N1601-N1650/N1648.pdf .

    The second part would be a matter of writing a filter, or learning from Doxygen code how it parses Fortran structures.

  3. PeterP says:

    If your Fortran compiler can be set to generate output object files in the ELF format (see http://en.wikipedia.org/wiki/Executable_and_Linkable_Format) with debug info, type information for all symbols in the global symbol table can be found in the debug sections (see http://dwarfstd.org/Dwarf3.pdf for the debug info specification).

    It should be straightforward to convert this into the corresponding C declarations.
    As the info comes from the object file, this also means that the mapping from unmangled to mangled names must be in the file, too (otherwise source code debugging would not work), courtesy of your compiler!

  4. Frank says:

    @jldugger; ANTLR grammar:
    The first interesting Google hit for “Fortran ANTLR grammar” pointed to the Open Fortran Parser which looked promising but I encountered some problems while compiling it that I couldn’t fix easily. Thus I didn’t look further into it.

    @Alberto; ISO_C_BINDING + Doxygen parser:
    Alberto, you are of course right that the intrinsic Fortran 2003 module ISO_C_BINDING solves the problem of name mangling and knowing the right C types for the corresponding Fortran types. But if one is bound to older Fortran standards this is not an option. I also tried to “misuse” Doxygen for what I want to accomplish but instead of touching the parser code, I looked into transforming Doxygen’s XML output to C declarations. But it seemed that the types of function parameters weren’t available in the XML output. So I also skipped this option.

    @PeterP; DWARF debugging infos:
    Using debugging infos from object files to create source code is another interesting idea. I actually wrote a simple and half done script (dwarf2cdecl.py) that can extract functions with their parameters from the output of dwarfdump -di. However, I think that this approach is to fragile and not as straightforward as I’d like it.

    So I’m still open to suggestions.

Leave a Reply