Next: Classes Up: Introduction to C++ Previous: Functions and Function

Interfacing to FORTRAN

Understanding this section is not necessary to understand most of the code in this manual, but we are documenting here what we have learned about this subject, which is hard to find elsewhere.

C++ programs can call subroutines written in FORTRAN, and access global common blocks declared in FORTRAN routines. Using the IBM RS6000 XLF compiler (or many other UNIX FORTRAN compilers) may introduce trailing underscores to subroutine or common block names, depending on the compiler options. FORTRAN routines must be forward declared before they are invoked. Also, C++ must be warned that the subroutine is not a C++ routine. This is done with the keyword "C". So a forward declaration might look like this:


extern "C" void dendu_();

Common blocks are accessed by giving a C++ global variable (a simple variable, an array or a structure) the same name as the FORTRAN COMMON block.

So the FORTRAN


      common /abc/ n,f(10)

may be accessed by the C/C++


struct {
  int n;
  float f[10];
} abc_;

This defines a structure called abc_; the C/C++ program may refer to abc_.n or abc_.f[0].

FORTRAN subroutines expect everything to be passed by reference. One may use either C++ pointers or references to accomplish this. Thus, one may use either


extern "C" void forsub_(int&);
int j;
forsub_(j);

or


extern "C" void forsub_(int*);
int j;
int *jp;                        // jp is a pointer to an int
jp = &j;                        // jp now contains the address of j
forsub_(jp);                    // this effectively passes j to FORTRAN

If you write C++ routines to be called by FORTRAN, all the simple shorts, ints and floats should be received by reference. Thus, the FORTRAN call


      CALL DUSER(IPASS,ITIMES)

may be satisfied by the C++ function whose definition begins


void duser_(int& ipass, int& itimes)
...

To call a FORTRAN subroutine that takes string arguments, XLF expects extra arguments beyond those you see in the FORTRAN source code - for each char* argument in the explicit argument list you must append to the end of the argument list an additional argument that gives the length of the string. The C++ programmer must provide these string lengths explicitly. The string lengths are passed by value.

Thus the FORTRAN routine


        SUBROUTINE DSAGET(RTYPE,INDEX0,OFFSET,N,JDATA,IERR)
        CHARACTER * (*) RTYPE
        INTEGER INDEX0, OFFSET, N, JDATA(10), IERR

may be forward-declared to C++ like this:


extern "C" void dsaget_(char* rtype,int& index,int& offset,int& n,int& data,
                        int& err,int len); // len is the extra argument

and called like this:


char cArray[80] = "TIME";
float f[100];
dsaget_(cArray,1,1,10,f[0],ierr,4); // the 4 gives the length of string in cArray



Next: Classes Up: Introduction to C++ Previous: Functions and Function


walter@
Wed Aug 10 11:53:26 PDT 1994