Note: This portion of the documentation definitely needs a lot of work!
The following discussion assumes that you are running g77
in f2c
compatibility mode, i.e. not using `-fno-f2c'.
It provides some
advice about quick and simple techniques for linking Fortran and C (or
C++), the most common requirement.
For the full story consult the
description of code generation.
See section Debugging and Interfacing.
When linking Fortran and C, it's usually best to use g77
to do
the linking so that the correct libraries are included (including the
maths one).
If you're linking with C++ you will want to add
`-lstdc++', `-lg++' or whatever.
If you need to use another
driver program (or ld
directly),
you can find out what linkage
options g77
passes by running `g77 -v'.
Even if you don't actually use it as a compiler, f2c
from
@uref{ftp://ftp.netlib.org/f2c/src}, can be a useful tool when you're
interfacing (linking) Fortran and C.
See section Generating Skeletons and Prototypes with f2c
.
To use f2c
for this purpose you only need retrieve and
build the `src' directory from the distribution, consult the
`README' instructions there for machine-specifics, and install the
f2c
program on your path.
Something else that might be useful is `cfortran.h' from
@uref{ftp://zebra/desy.de/cfortran}.
This is a fairly general tool which
can be used to generate interfaces for calling in both directions
between Fortran and C.
It can be used in f2c
mode with
g77
---consult its documentation for details.
Generally, C code written to link with
g77
code--calling and/or being
called from Fortran--should `#include <g2c.h>' to define the C
versions of the Fortran types.
Don't assume Fortran INTEGER
types
correspond to C int
s, for instance; instead, declare them as
integer
, a type defined by `g2c.h'.
`g2c.h' is installed where gcc
will find it by
default, assuming you use a copy of gcc
compatible with
g77
, probably built at the same time as g77
.
f2c
A simple and foolproof way to write g77
-callable C routines--e.g. to
interface with an existing library--is to write a file (named, for
example, `fred.f') of dummy Fortran
skeletons comprising just the declaration of the routine(s) and dummy
arguments plus END
statements.
Then run f2c
on file `fred.f' to produce `fred.c'
into which you can edit
useful code, confident the calling sequence is correct, at least.
(There are some errors otherwise commonly made in generating C
interfaces with f2c
conventions,
such as not using doublereal
as the return type of a REAL
FUNCTION
.)
f2c
also can help with calling Fortran from C, using its
`-P' option to generate C prototypes appropriate for calling the
Fortran.(2)
or @uref{ftp://ftp.dsm.fordham.edu} is
probably better for this purpose.}
If the Fortran code containing any
routines to be called from C is in file `joe.f', use the command
f2c -P joe.f to generate the file `joe.P' containing
prototype information.
#include
this in the C which has to call
the Fortran routines to make sure you get it right.
See section Arrays (DIMENSION), for information on the differences
between the way Fortran (including compilers like g77
) and
C handle arrays.
f2c
can be used to generate suitable code for compilation with a
C++ system using the `-C++' option.
The important thing about linking g77
-compiled
code with C++ is that the prototypes for the g77
routines must specify C linkage to avoid name mangling.
So, use an `extern "C"' declaration.
f2c
's `-C++' option will take care
of this when generating skeletons or prototype files as above, and also
avoid clashes with C++ reserved words in addition to those in C.
Unlike with some runtime systems, it shouldn't be necessary (unless there are bugs) to use a Fortran main program unit to ensure the runtime--specifically the I/O system--is initialized.
However, to use the g77
intrinsics GETARG
and IARGC
,
either the main
routine from the `libg2c' library must be used,
or the f_setarg
routine
(new as of egcs
version 1.1 and g77
version 0.5.23)
must be called with the appropriate argc
and argv
arguments
prior to the program calling GETARG
or IARGC
.
To provide more flexibility for mixed-language programming
involving g77
while allowing for shared libraries,
as of egcs
version 1.1 and g77
version 0.5.23,
g77
's main
routine in libg2c
does the following, in order:
f_setarg
with the incoming argc
and argv
arguments,
in the same order as for main
itself.
This sets up the command-line environment
for GETARG
and IARGC
.
f_setsig
(with no arguments).
This sets up the signaling and exception environment.
f_init
(with no arguments).
This initializes the I/O environment,
though that should not be necessary,
as all I/O functions in libf2c
are believed to call f_init
automatically,
if necessary.
(A future version of g77
might skip this explicit step,
to speed up normal exit of a program.)
f_exit
to be called (with no arguments)
when the program exits.
This ensures that the I/O environment is properly shut down
before the program exits normally.
Otherwise, output buffers might not be fully flushed,
scratch files might not be deleted, and so on.
The simple way main
does this is
to call f_exit
itself after calling
MAIN__
(in the next step).
However, this does not catch the cases where the program
might call exit
directly,
instead of using the EXIT
intrinsic
(implemented as exit_
in libf2c
).
So, main
attempts to use
the operating environment's onexit
or atexit
facility, if available,
to cause f_exit
to be called automatically
upon any invocation of exit
.
MAIN__
(with no arguments).
This starts executing the Fortran main program unit for
the application.
(Both g77
and f2c
currently compile a main
program unit so that its global name is MAIN__
.)
onexit
or atexit
is provided by the system,
calls f_exit
.
exit
with a zero argument,
to signal a successful program termination.
exit
doesn't exit on the system.
All of the above names are C extern
names,
i.e. not mangled.
When using the main
procedure provided by g77
without a Fortran main program unit,
you need to provide MAIN__
as the entry point for your C code.
(Make sure you link the object file that defines that
entry point with the rest of your program.)
To provide your own main
procedure
in place of g77
's,
make sure you specify the object file defining that procedure
before `-lg2c' on the g77
command line.
Since the `-lg2c' option is implicitly provided,
this is usually straightforward.
(Use the `--verbose' option to see how and where
g77
implicitly adds `-lg2c' in a command line
that will link the program.
Feel free to specify `-lg2c' explicitly,
as appropriate.)
However, when providing your own main
,
make sure you perform the appropriate tasks in the
appropriate order.
For example, if your main
does not call f_setarg
,
make sure the rest of your application does not call
GETARG
or IARGC
.
And, if your main
fails to ensure that f_exit
is called upon program exit,
some files might end up incompletely written,
some scratch files might be left lying around,
and some existing files being written might be left
with old data not properly truncated at the end.
Note that, generally, the g77
operating environment
does not depend on a procedure named MAIN__
actually
being called prior to any other g77
-compiled code.
That is, MAIN__
does not, itself,
set up any important operating-environment characteristics
upon which other code might depend.
This might change in future versions of g77
,
with appropriate notification in the release notes.
For more information, consult the source code for the above routines. These are in `egcs/libf2c/libF77/', named `main.c', `setarg.c', `setsig.c', `getarg_.c', and `iargc_.c'.
Also, the file `egcs/gcc/f/com.c' contains the code g77
uses to open-code (inline) references to IARGC
.