[net.lang.f77] calling c routines from fortran

lizh@athena.UUCP (Liz Heller) (11/15/84)

Has anyone had experience with calling c routines from fortran 77 on 4.2
unix? Know of any articles, pitfalls? The way I'm thinking of doing it
is as follows (fortran 77 program "x" really wants to call c routine "z",
but instead calls c routine "y"):

	"x"
	  call to "y"

	"y"
	  manipulate arguments for call to "z"
	  call to "z"

	"z"
	  ...

The c routines are fixed - I can't change the way they're called. Anyone
know a better way to do this?

Liz Heller

woods@hao.UUCP (Greg "Bucket" Woods) (11/19/84)

> Has anyone had experience with calling c routines from fortran 77 on 4.2
> unix? Know of any articles, pitfalls? 

   Unfortunately, due to the fact that F77 insists on appending a "_" to all
of it's routine names, you cannot call *any* C routine from F77 unless it's
name ends in "_". In addition to that, all F77 arguments are pointers, so you
can't even call a routine whose name ends in "_" if it is expecting any non-
pointer arguments (usually the case in C). Therefore, the only way to do this 
is the following (which is what I gather Liz was suggesting) (suppose you want
to call routine "z" which returns an int and has one int argument):

....
      iretvl=iz(intvar)
....

int iz_(intvar)  int *intvar;
{
int z(); /* this declaration not necessary for int functions */
   return(z(*intvar));
}

  I know this is kludgy, but I use it all the time and it works fine. It's the
only thing you can do (well, maybe you could write the intermediate routine
in assembly, but I doubt if you could gain much efficiency that way, and it's
a lot more confusing).
   For a reference, see the paper "A Portable Fortran 77 Compiler" by S. I. 
Feldman and P.J. Weinberger, which, among other places, appears in the "Volume
2C" manual which came with our 4.2BSD manuals.

--Greg "FORTRAN hacker" Woods
-- 
{ucbvax!hplabs | allegra!nbires | decvax!stcvax | harpo!seismo | ihnp4!stcvax}
       		        !hao!woods
   
     "...once in a while you can get shown the light
         in the strangest of places if you look at it right..."

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (11/20/84)

Also watch out for interference with the F77 run-time system if the
called C routines do any I/O.

lizs@munnari.OZ (Liz Sonenberg) (11/24/84)

>    Unfortunately, due to the fact that F77 insists on appending a "_" to all
> of it's routine names, you cannot call *any* C routine from F77 unless it's
> name ends in "_". In addition to that, all F77 arguments are pointers, so you
> can't even call a routine whose name ends in "_" if it is expecting any non-
> pointer arguments (usually the case in C). Therefore, the only way to do this 
> is the following (which is what I gather Liz was suggesting)
>[  details of proposed method comes here ]

  Actually there is a rather horrible kludge for passing an immediate value
(rather than a pointer) directly from an f77 program to a c procedure.
Suppose you want to call the c procedure whose synopsis is

	int z_(intvar)	int intvar;

The following f77 code will pass the value of the integer quantity i to the
procedure  z_  as an immediate value

	   ...
	character*1 x(2)
	   ...
	iretval = z( x( i + 1 - loc(x) )
	   ...

(provided your machine is byte-addressable, and each character occupies a
single byte).  Naturally, you would have to compile the resulting program
without the -C option so that no run-time checking of array subscripts will
be performed.

  Getting access to immediate values that are passed back the other way is a
different story, however, and I know of no convenient way of doing it.

  It is also possible to circumvent the compiler's (very irritating) procedure
of appending underscores to all user-established global variables, provided
the name of the c routine you want to call contains at least two characters.
When calling the routine from your f77 program, give it any convenient name
that contains one less character.  After compiling (but not linking) the f77
progam, the temporary name you have given the routine will appear in the string
table of the object file with an underscore appended.  It is not particularly
difficult to replace this with the true name of the routine you want to call
( I have a rudimentary c program for doing this, if anyone is interested ).
After the modified object file has been linked with the appropriate c files or
libraries, your f77 program will then call the correct routine.

					David Wilson

					{ ...!decvax!munnari!lizs }