[net.unix-wizards] linking C and Fortran

johnston@lbl-csam.arpa (Bill Johnston [csam]) (07/30/86)

What needs to be done (other than ensuring consistent data types
for args) in order to link C and/or Fortran main programs and
routines with each other? How do the necessary libraries get
specified at link time (manually?), and what else needs to be done?
I mostly need to call Fortran from C, but visa versa also.

For example:

	f77 -c forsub.f
	forsub.f:
      	   forsub:
	
	cc -c cmain.c
	cc cmain.o forsub.o -o cmain
	Undefined:
	_forsub

I could understand why there might be some missing Fortran references
generated in forsub since cc doesn't reference the Fortran library.
But why isn't forsub found?

Any help or pointers to information would be appreciated.

	Thanks, Bill Johnston
	[wejohnston@lbl.arpa, ...ucbvax!lbl-csam!johnston]

moss@BRL.ARPA (Gary S. Moss (SLCBR-VLD-V)) (07/30/86)

Bill,
	CC prepends an underscore to the function name, and F77 appends
an underscore.  So, to call Fortran from C, name the function _forsub in
the Fortran module, invoke it as forsub_ in the C module.  You may have
to shorten the name to allow for the extra characters, depending on your
linker.  Conversely, define it as forsub_ in the C module, and invoke it
as _forsub in the Fortran module.  Be sure to define/invoke the function
from C with pointers (call by reference) exclusively.

-moss.

levy@ttrdc.UUCP (Daniel R. Levy) (08/03/86)

In article <2668@brl-smoke.ARPA>, moss@BRL.ARPA (Gary S. Moss (SLCBR-VLD-V)) writes:
>Bill,
>	CC prepends an underscore to the function name, and F77 appends
>an underscore.  So, to call Fortran from C, name the function _forsub in
>the Fortran module, invoke it as forsub_ in the C module.  You may have
>to shorten the name to allow for the extra characters, depending on your
>linker.  Conversely, define it as forsub_ in the C module, and invoke it
>as _forsub in the Fortran module.  Be sure to define/invoke the function
>from C with pointers (call by reference) exclusively.
>-moss.

Close but no cigar.  Fortran (at least f77 which mostly follows the ANSI
standard) doesn't grok '_' in identifiers and even if it did (a la VMS FORTRAN)
the above explanation has an error in it.  The actual situation might look
like this:

      subroutine forsub(arg1, arg2,...)
      ....
      return
      end

main(argc,argv);
int argc;
char **argv;
{
	void forsub_();
	void f_init();
	void f_exit();
	void exit();
	...	/* other declarations */
	f_init();	/* a MUST for many UNIX f77's if the subroutines */
			/* do I/O; there have been many net inquiries about */
			/* this from time to time */
	....
	forsub_(&arg1, &arg2,...);
	...
	f_exit();	/* flushes, truncates, and closes opened files */
			/* among other things; should be done if fortran */
			/* I/O was done in the program */
	exit(0);
}

Anyone who has been having trouble interfacing C and f77 can send further
questions my way.  I am not an expert nor am I involved with f77 or C design
but I have had quite a bit of experience with this kind of interface under
several different versions of UNIX.

UNIX is a registered trademark of AT&T Bell Laboratories.
-- 
 -------------------------------    Disclaimer:  The views contained herein are
|       dan levy | yvel nad      |  my own and are not at all those of my em-
|         an engihacker @        |  ployer or the administrator of any computer
| at&t computer systems division |  upon which I may hack.
|        skokie, illinois        |
 --------------------------------   Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
	   go for it!  			allegra,ulysses,vax135}!ttrdc!levy

levy@ttrdc.UUCP (Daniel R. Levy) (08/03/86)

In article <1103@ttrdc.UUCP>, levy@ttrdc.UUCP (Daniel R. Levy) writes:
>Close but no cigar.  Fortran (at least f77 which mostly follows the ANSI
>standard) doesn't grok '_' in identifiers and even if it did (a la VMS FORTRAN)
>the above explanation has an error in it.  The actual situation might look
>like this:
>
>      subroutine forsub(arg1, arg2,...)
>      ....
>      return
>      end
>
>main(argc,argv);
>int argc;
>char **argv;
>{
>.
>.
>.

Whoops!!!  Omit the semicolon in the "main(argc,argv)" line.  A typo.  SORRY!
-- 
 -------------------------------    Disclaimer:  The views contained herein are
|       dan levy | yvel nad      |  my own and are not at all those of my em-
|         an engihacker @        |  ployer or the administrator of any computer
| at&t computer systems division |  upon which I may hack.
|        skokie, illinois        |
 --------------------------------   Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
	   go for it!  			allegra,ulysses,vax135}!ttrdc!levy

mouse@mcgill-vision.UUCP (der Mouse) (08/14/86)

In article <2668@brl-smoke.ARPA>, moss@BRL.ARPA (Gary S. Moss (SLCBR-VLD-V)) writes:
> 	CC prepends an underscore to the function name, and F77 appends
> an underscore.  [Explanation, basically that f77 _forsub <-> C forsub_]

Well, I don't know what system you're on, but on all UNIX f77s I know
of, f77 appends an underscore and hands the result to the C compiler,
at least conceptually.  The result is that C ultimately prepends an
underscore and f77 *both* appends *and* prepends underscores.  The net
result is that what f77 knows as "forsub" is what C knows as "forsub_".

> Be sure to define/invoke the function from C with pointers (call by
> reference) exclusively.

Good point.  Also make sure the pointers point to something!  Probably
the commonest problem I see with pointers here is

	something *ptr;
	routine(ptr);

because they've been told that "routine" takes a "pointer to something"
as its argument.  They never notice that this pointer has to point to
a "something".
-- 
					der Mouse

USA: {ihnp4,decvax,akgua,utzoo,etc}!utcsri!mcgill-vision!mouse
     think!mosart!mcgill-vision!mouse
Europe: mcvax!decvax!utcsri!mcgill-vision!mouse
ARPAnet: utcsri!mcgill-vision!mouse@uw-beaver.arpa

"Come with me a few minutes, mortal, and we shall talk."
			- Thanatos (Piers Anthony's Bearing an Hourglass)