The extern "C" directive
First of all, the extern "C" linkage specification must be used
to declare any modules that are not written in C++.
Case sensitivity C++ is a case sensitive language, Fortran is not. All reference to Fortran symbols my be specified in lowercase in C++ calls.
The underscore (_)
In many Fortran compilers, an underscore (_) is appended by default at the end
of definitions and references to externally visible symbols (subroutines,
functions, etc.). This happens for Solaris and
Digital UNIX f77 compilers, for g77 compiler and for
hepf77 compiler interface; on HP-UX the +ppu option
must be added to the f77 compiler to activate this feature;
on AIX -qextname must be added to the xlf compiler.
The appended underscore is a
standard for HEP Fortran libraries (e.g. CERNLIB). In a C++
call the Fortran subroutines or functions must be
specified with an appended underscore.
Passing parameters An important thing to remember is that C++ passes all parameters by value (except arrays and structures). Fortran passes them by reference. It is therefore necessary to specify in the C++ function prototypes that the Fortran subroutines and functions expect call-by-reference arguments using the address-of (&) operator.
To resume the previous points with an example, consider the Fortran function:
It must be called from C++ as:
Arrays
C++ stores arrays in row-major order, whereas Fortran stores arrays in
column-major order. The lower bound for C++ is 0, for Fortran is 1.
This mean that the Fortran array element myarray(1,1) corresponds
to the C++ array element myarray[0][0]; whereas
myarray(6,8) corresponds to myarray[7][5];
Fortran Files Fortran I/O routines require a logical unit number to access a file, C++ accesses files using UNIX I/O routines and intrinsics and requires a stream pointer. A Fortran logical unit CANNOT be passed to a C++ routine to perform I/O on the associate file, NOR CAN a C++ file pointer be used by a Fortran routine.
Fortran Subroutines
C++ does not distinguish between subroutines and functions. All subprograms
are treated as functions. Fortran subroutines can be seen as functions not
returning a value:
Fortran common areas
Fortran common areas can be accessed by C++ by defining a structure type
and a variable of this type to be defined
extern (also
in this case an underscore must be added at the end of C++ variable related
to the Fortran common area):
Fortran strings (
character*N)
Fortran character parameters are generally passed by descriptor.
C++ char defines simply a byte; in this language, strings are
arrays of bytes
terminating with a null byte ('\0'). Exchanging string parameters
between different languages could introduce additional difficulties in porting.
With g77 the libg2c.a must be added at linking time
to allow strings exchange. Anyway, in general this should work:
How to compile and link
Obviously the C++ and Fortran source files must be compiled separately using
the opportune compiler. Linker must be called via the C++ compiler as the main
program lies in the C++ source files:
A global example A working example that includes what described above can be found here:
The C++ source: c1.cc
The Fortran source: f1.f
The gnu make file: GNUmakefile