for current thoughts and progress on this. This CEP will be updated properly over the summer some time...

Overall strategy and compiler support

The strategy is to have Cython generate a Fortran source file from the pyx/pxd sources, together with the C file, which must also be compiled and linked into the resulting .so/DLL. This file contains automatically generated bindings necesarry to call the functions like if they were written in C. The Fortran file target is in the Fortran 90 language with the addition of Fortran 2003 ISO C bindings. Using these bindings means that one is using a standardized way of bridging between Fortran and C. This takes care of calling convention, Fortran name mangling, etc. etc.

Any Fortran compiler with Fortran 2003 ISO C bindings support should work. Newer versions of the open source gfortran and g95 does this; as well as the popular Intel Fortran compiler. Even if the end-user is using F77 code, usually a Fortran compiler is available which can properly link in the F77 code while still supporting compilation of the Cython wrapper.

then a) the out value of foo will not be passed back to Cython, but discarded, and b) values too large for short will silently overflow in the Fortran wrapper.

Passing arrays

Fortran doesn't support pointers, but has a native array type which can be passed in a variety of ways (three or four I think). The ISO C bindings fully support passing contiguous arrays in various ways. This involves a function call in Fortran which casts a special (opaque) type to a Fortran array; where one must provide the shape information.

Depending on the call, the shape information may be present in the signature of the function (F77 style arrays) or not (F90 assumed shape arrays). In the latter case, we must pass a struct containing both the pointer and the shape information. (Note that the struct to be passed is entirely up to us, as we generate both sides of the bridge -- generated C code passes the struct to generated Fortran code which uses it to cast to a proper Fortran array object.)

To pass non-contiguous arrays, the simplest thing is probably to pass the original, non-strided buffer, together with stride information, and then do the appropriate slicing Fortran-side. If dimensions needs reordering, then Fortran's reshape function can be used (it copies data, but it's still easier than copying Cython-side). Result: If the Fortran function to be called operates on strided arrays and the ordering is correct, the correctly sliced array is passed, and if not, the Fortran compiler will transparently copy in and copy out. It is good to push as much copying as possible to the Fortran compiler as it can better determine how it should be done.

Fortran types

In the above, C types has been used. This will work in the sense that only truncation/overflows will happen, the stack will not be destroyed. But it is always good to use the exact same type in Fortran and C.

To this end a new virtual Cython module cython.fortran should be created, containing Fortran equivalents. Examples:

These should ultimately boil down to the equivalent types in C. (The C compiler will know the exact type; while Cython will not know the size of the type). This is likely implemented by including a fortran.h controlled by compiler directives containing information about a supported set of compilers. If necesarry, a program could be written to generate such a header file by probing the Fortran and C compilers.

Build system

One also needs to modify distutils enough to reliably build these modules. This likely involves using NumPy's additions to distutils for compiling Fortran code, and integrate that with Cython's distutils.

Optional: Parsing Fortran files

It would nice to (optionally) be able to parse Fortran directly for function declarations, rather than having to use a pxd file. I have had a quick look on about four different Fortran parsers; all appear to have their weaknesses but some of them could probably be tweaked enough to be useful.