Skip to main content

Sara Fortuna

Fortran and C++

A lot of excellent numerical software is written in Fortran77, and it may be useful to call a FORTRAN routine from a C/C++ program.

Here we report a few examples to illustrate how to link the two codes.

1. Calling Fortran77 functions from C++

Let's suppose we want to use the following function to calculate and print the square of a number in our C++ code. In this example, the C++ code will simply ask for a number and pass its reference to the fortran function.

Fortran77 code:

This is the "squaref.f" file content:

FUNCTION SQUARE(n)
REAL n
write(*,*) n*n
END


Before including this function in our C++ code, we should remember that:

in the C++ code, the function name should be in lower case, followed by an underscore, and the arguments should be pointers :o)

and:

we should convert also the names of the datatypes

Fortra77 C++  
real float  
real*8 double  


Therefore, the C++ code will appear as follows.

C++ code:

This is the "squarec.cpp" file content:

#include <iostream>
using namespace std;

extern "C" void square_(float* n);

// calling Fortran function as an external C function avoid name mangling

int main()
{
float n;
cout<< "give me a number!";
cin>>n;
square_(&n);
return (0);
}

 

Files:

squarec.cpp

squaref.f

How to compile:

The following commands work on my LINUX desktop to compile the files and generate a program called "square":


> f77 -c squaref.f
> g++ -c squarec.cpp
> g++ -o square squarec.o squaref.o -lg2c

For older compilers:


> g++ -o test_run test_f.o test_c++.o external.o -lf2c

If the compiler is unable to locate the -lg2c library, type:


> locate libg2c.so
/usr/lib/libg2c.so
> g++ -o square squarec.o squaref.o /usr/lib/libg2c.so

More details can be found in the following references.

References:


2. Global variables & Common Blocks

If we need a global variable (ie: a variable that "live" outside the codes), we should define a Common Block in Fortran and a corresponding structure in C++.

In the following example, the C++ code asks for 4 numbers and places them in an array. The Fortran subroutine asks a number and add it to each element of the array. To do that, the array is defined as a global variable.

Fortran77 code:

This is the "addf.f" file content:

SUBROUTINE ADD()

 REAL::n(4)
 COMMON /coeff/ n

Common block

REAL::k
write (*,*) "gimme a number to add:"
read (*,*) k
DO 10 i=1,4
n(i)=n(i)+k
10 continue
RETURN
END

 

C++ code:

This is the "addc.cpp" file content:

#include <iostream>
using namespace std;

extern "C" void add_();

extern "C"
{
extern struct
{
float n[4];
}
coeff_;
}

This structure calls the Fortran Common block.

int main()
{
cout<< "give me 4 numbers:"<<endl;
for (int i=0;i<4;i++)
{
cin>>coeff_.n[i];
}
add_();
cout<< "now the numbers are:"<<endl;
for (int i=0;i<4;i++)
{
cout<<coeff_.n[i]<<endl;
}
return (0);
}

How to compile:

The following commands generate a program called "add":


f77 -c addf.f
g++ -c addc.cpp
g++ -o add addc.o addf.o -lg2

References:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

name mangling C++ compiler modify the function's name (this is useful for overloaded functions), but in this case we do not want it to do that!