Mixed Language Programming in Fortran and C++ with Compaq Visual Fortran (CVF)and Borland C++ Builder (BCB)

I want to limit the description to programming with the Borland and Compaq compilers, but most of the elements also will apply to other compilers. Carsten Arnholm gives a general and detailed introduction on his page, how to mix Fortran and C++. Therefore I will not repeat general remarks but directly start with examples. I compiled the code samples with Borland C++ Builder 5 and Compaq Visual Fortran 6.6.

Let's have a look on a simple Fortran90 routine

REAL(KIND(0.d0)) FUNCTION square(x)
! Specify that the routine name is to be made available to callers of the
! DLL and that the external name should not have any prefix or suffix
!DEC$ ATTRIBUTES DLLEXPORT :: square
!DEC$ ATTRIBUTES ALIAS:'square' :: square
REAL(KIND(0.D0)) :: x [VALUE] ! pass by value
square = x*x
END FUNCTION

and the C++ routine calling the Fortran90 function

#include <iostream.h>
extern "C" double __stdcall square(double x);
int main(int argc, char* argv[])
{
double a=4;
double asq = square(a);
cout << a << " " << asq << endl;
return 0;
}


The argument is passed by value. To transfer the code from Fortran to C++ a dynamic link library with the extension .dll is created in Compaq Visual Fortran (CVF). To transform the CVF library into Borland C++ Builder (BCB) form you have to use the BCB utility implib. Then you copy the dll and lib files to the BCB project directory and include the lib file into the project and start compiling and linking. That's it :-)

If you want to pass an array you have to do that by reference in Fortran90 and use a pointer in C++:

Fortran90 function:

SUBROUTINE c_zsn(m,d,k,f,zsn,nf)

! Specify that the routine name is to be made available to callers of the
! DLL and that the external name should not have any prefix or suffix

!DEC$ ATTRIBUTES DLLEXPORT :: c_zsn
!DEC$ ATTRIBUTES ALIAS:'c_zsn' :: c_zsn
!DEC$ ATTRIBUTES VALUE :: m,d,k,nf
!DEC$ ATTRIBUTES REFERENCE :: f,zsn

IMPLICIT NONE

INTEGER :: nf,i
REAL(KIND(0.D0)) :: m,d,k,f(0:(nf-1)),zsn(0:(nf-1)),om,pi
COMPLEX(KIND(0.D0)) :: j

j = (0.d0, 1.d0)
pi = 4.d0 * datan(1.d0)

do i=0,nf-1
om = 2.d0*pi*f(i)
zsn(i) = abs(-om**2*m-j*om*d+k)
end do

END SUBROUTINE

and the C++ routine calling the Fortran90 function

#include <iostream.h>
extern "C" void __stdcall c_zsn(double m,double d,double k,double *f,
double *zsn,int nf);
int main(int argc, char* argv[])
{
double m = 2.;
double k = 200.;
double d = 0.01;
int nf = 10;
double *f = new double[nf];
double *zsn = new double[nf];
for (int i=0; i<nf; i++) f[i]=i;
c_zsn(m,d,k,f,zsn,nf);
for (int i=0; i<nf; i++)
cout << i << " " << f[i] << " " << zsn[i] << endl;
delete [] f;
delete [] zsn;
return 0;
}

Please have a look on the Compaq Visual Fortran documentation regarding passing of higher dimensional arrays. You have to be careful: For a arr(:) definition (deferred shape) the descriptor is passed but for a fixed shape definition arr(100)Ithe array pointer or array is passed by base address, which is like passing the first element of an array.

 

Some general remarks at the end:

If you want the Fortran and C++ projects, please send me a mail.

I am using Fortran as a "number cruncher". Fortran 90/95 is a wonderful and very comfortable tool (comparable with Matlab regarding coding speed) to write fast simulation applications and Borland C++ Builder is one of the best tools to wrap the Fortran code into a GUI. I tried Visual Basic and Visual C++ and from my point of view Borland C++ Builder beats them all. It is as simple as Visual Basic but offers more capabilities.

At the moment I'm switching to Python, which is a simple and yet very powerful language. I'm sure Python will convince many scientists and engineers which at the moment still use Matlab. Have a look at the Python homepage and my Python page for structure mechanics applications.




Copyright ©2000-2002 Markus Faust, all rights reserved
Version 0.0.4 vom 19.05.2002