[comp.lang.c++] How to call C++ functions from Fortran with C++ 2.0

saito@sdr.slb.com (Naoki Saito) (03/14/90)

	Last year, Jeff Filo @ Purdue Univ, posted the article about how to
call C++ from C and Fortran.  Switching to C++ 2.0, however, makes the problem
messier.  Of course, calling Fortran subroutines from C++ is easy, but the
reverse is not.  The following artificial programs illustrate the situation.

Fortran main program (I want to use C++ square function):
	program test
c
	integer*4 i, j
	i = 100
	call square(i, j)
	write(6,*) i, j
	end

C++ program:
void square(int& i, int& j)
{
  j = i*i;
}

In order to make executable image, I had to
(1) Translate the C++ program to the C program.
The translation changes function name in C++ 2.0 as follows:
char square__FRiT1 (__0i , __0j )
int *__0i ;
int *__0j ;
{ 
((*__0j ))= (((*__0i ))* ((*__0i )));
}

(2) Modify the function name which is callable from Fortran.
Fortran is not case sensitive. The underscore must be appended too.
in C++,
char square__FRiT1 (__0i , __0j ) ==> char square__frit1_ (__0i , __0j )
 						   ^^^^^^
in Fortran,
call square(i, j) ==> call square__frit1(i, j)

(3) Finally, compile and link them.

Of course, the above example is very artificial and stupid, but the process
is rather complicated.  This kind of situation sometimes occurs if we have
developed classes in C++ and want to plug them in the old existing Fortran
programs such as graphics systems.
Does anyone have good idea about this?  I would like to emphasize again:
calling Fortran subroutines or C functions from C++ is "easy".  However,
the reverse, especially, calling C++ 2.0 from Fortran doesn't seem easy.

Thanks in advance,

-- 
Naoki Saito (saito@sdr.slb.com)
Schlumberger-Doll Research

jac@muslix.llnl.gov (James Crotinger) (03/15/90)

  Another approach would be to make square() and 'extern "C"'
function.  For instance:

  extern "C" void SQUARE(int *i, int*j);

  void SQUARE(int *i, int *j)
  {
    *j = *i * *i;
  }

In fortran this would be called simply as:

  call square(i,j)

BTW, you're example used references for i and j. I would think that
this, too, might be very implementation dependent. I don't believe
that there is any gaurantee in the language that a function which
takes a reference actually work as though it takes a pointer. 

Also, you translated the name to lower case:

  char square__FRiT1 (__0i , __0j ) ==> 
                       char square__frit1_ (__0i , __0j )

If this isn't incorrect, it is at least system dependent as
fortran symbols are supposed to be presented to the linker
in upper case. 

  Of course what there should be is 'extern "FORTRAN"' statement which
would handle not only name demangling, but also would get the case
correct for whatever system you happen to be running on and would
also allow proper use of references.

  Jim