Fortran & C - Mixing Fortran & C |
The following are examples that demonstrate how to call Fortran from C or vice versa. This has also been worked into individual slides (or a collected version).
- Fortran & C differences
- Cray Fortran & C data types
- IBM Fortran & C data types
- Fortran to C:
- f2c.f
- f2cfn.c
- compilation steps
- output
- C to Fortran:
- c2f.c
- c2ffn.f
- compilation steps
- output
Fortran & C differences
- Fortran :
- Passes by address
- Routine names are case insensitive
- Arrays are column-major
- Strings contain length
- C :
- Passes by value
- Names are case sensitive
- Arrays are row-major
- ``Strings'' are null terminated
These demo codes use the Cray C predefined macro _CRAY to conditionally compile any Cray dependent parts, _AIX for any IBM xlc dependent parts, and __hpux for HP machines. Most everything else are satisfied by the defaults.
Note that for the Cray that the C parts need to convert Fortran character strings to C char pointers. On workstations this is usually no problem. In addition, since Fortran is case insensitive Cray Fortran defaults subroutine names to UPPERCASE. Workstations default to lowercase with an underscore (_) usually appended to the name.
Fortran C size(bits) INTEGER
int
46/64 cft77 -i64 cc -nofastmd INTEGER
long
64 REAL
double
orfloat
64 DOUBLE PRECISION
long double
128 COMPLEX
float complex
ordouble complex
128 SUBROUTINE SUBR( )
void SUBR( )
FUNCTION FN( )
double FN( )
COMMON /CB/data(10)
struct common {
double data[10];
} CB;
The demo codes use the IBM C predefined macro _AIX to conditionally compile any IBM dependent parts.
In addition, since Fortran is case insensitive IBM Fortran defaults subroutine names to lowercase and does not append or prepend an underscore (_) to the name.
Fortran C size(bits) INTEGER*1
signed char
8 INTEGER*2
short
16 INTEGER
int
32 REAL
float
32 DOUBLE PRECISION
double
64 COMPLEX
2 float struct
64 DOUBLE COMPLEX
2 double struct
128 SUBROUTINE SUBR( )
void subr( )
FUNCTION FN( )
float fn( )
COMMON /CB/data(10)
?
f2c.f calls f2cfn.c
PROGRAM F2C C CHARACTER*32 NAME INTEGER AGE REAL TEMP C NAME = "Knut" C add null character at end for portable & safe handling by C NAME(LEN(NAME):LEN(NAME)) = CHAR(0) C note that LEN(NAME) = 32 in this case AGE = 4 TEMP = 98.6 CALL NAMEAGE(NAME, AGE, TEMP) END
f2cfn.c called by f2c.f
#include <string.h> #ifdef _CRAY # include <fortran.h> # define nameage NAMEAGE #else # if !defined(_AIX) && !defined(__hpux) # define nameage nameage_ # endif # define _fcd char * # define _fcdtocp(a) (a) # define _fcdlen(a) strlen(a) #endif void nameage(_fcd name, int *age, float *temp) { char *cp; size_t len; cp = _fcdtocp(name); /* convert to C char* */ len = _fcdlen(name); /* strip trailing blanks */ while (cp[len-1] == ' ' || cp[len-1] == '\0') --len; printf("Hello %.*s, who is %d years old, " "has a temperature of %4.1f\n", len, cp, *age, *temp); }Compilation Steps for the Above Example
- Cray - PVPs - UNICOS
cc -c f2cfn.c
cf77 f2c.f f2cfn.o
- (or substitute f90 for cf77)
- IBM - SP2 - AIX
xlc -c f2cfn.c
xlf f2c.f f2cfn.o
- SGI - IRIX
gcc -c f2cfn.c
f77 f2c.f f2cfn.o
- SUN - SunOS
gcc -c f2cfn.c
f77 f2c.f f2cfn.o
- HP - UX
gcc -c f2cfn.c
f77 f2c.f f2cfn.o
- PC - Linux
gcc -c f2cfn.c
g77 f2c.f f2cfn.o
Output for the Above Example
Hello Knut, who is 4 years old, has a temperature of 98.6
c2f.c calls c2ffn.f
#include <string.h> #ifdef _CRAY # include <fortran.h> # define nameage NAMEAGE #else # if !defined(_AIX) && !defined(__hpux) # define nameage nameage_ # endif # define _fcd char * # define _cptofcd(a,b) (a) # define _fcdlen(a) strlen(a) #endif void nameage(_fcd name, int *nlen, int *age, float *temp); int main() { char *name = "Knut"; _fcd fp; int nlen,age = 4; float temp = 98.6; nlen = strlen(name); fp = _cptofcd(name, nlen); /* convert to Fortran string */ nameage(fp, &nlen, &age, &temp); return 0; }
c2ffn.f called by c2f.c
SUBROUTINE NAMEAGE(NAME, NLEN, AGE, TEMP) CHARACTER*(*) NAME INTEGER NLEN,AGE REAL TEMP C WRITE(6,1000) NAME(1:NLEN),AGE,TEMP 1000 FORMAT(1X,'Hello ',A,', who is ',I2, . ' years old, has a temperature of ', f4.1) RETURN ENDCompilation Steps for the Above Example
To discover which libraries are necessary for Fortran modules, compile a short Fortran test program and add the-V
or-v
option (or whatever) to get a verbose execution listing to show what arguments are being passed to each compilation stage.
- Cray - PVPs - UNICOS
cf77 -c c2ffn.f
cc -c c2f.c
cf77 c2f.o c2ffn.o
- (or substitute f90 for cf77)
- IBM - SP2 - AIX
xlf -c c2ffn.f
cc c2f.c c2ffn.o -lxlf90 -lxlf -lm
- SGI - IRIX
f77 -c c2ffn.f
gcc c2f.c c2ffn.o -lF77 -lm -lU77 -lI77 -lisam -lmpc -lc
- SUN - SunOS
f77 -c c2ffn.f
gcc c2f.c c2ffn.o -L/usr/lang/SC0.0 -lF77 -lm -lc
- HP - UX
f77 -c c2ffn.f
gcc c2f.c c2ffn.o -lcl -lisamstub -lc
- PC - Linux
g77 -c c2ffn.f
gcc -c c2f.c
g77 c2f.o c2ffn.o
Output for the Above Example
Hello Knut, who is 4 years old, has a temperature of 98.6
Last Modified:
Brought to you by: R.K. Owen,Ph.D.
This page is http://owen.sj.ca.us/rkowen/howto/FandC/FandC.call.html