C calls FORTRAN subroutine

Donn Seeley donn at utah-gr.UUCP
Sat Oct 13 12:34:17 AEST 1984


>From the original article by Aldrin Leung:

	In the C program, I have
	----------
	#include <stdio.h>
	
	main()
	{
	try_()
	}
	----------
	
	In the Fortran program, I have
	----------
	      subroutine try
	      write (6,100)
	100   format ("subprogram")
	      end
	----------

When these routines are compiled, loaded together and run, they print
nothing.

The problem here is that f77's I/O system needs to be 'primed'.  The
standard f77 main() routine does this for you, but if you substitute
your own C main() routine then you have to do the 'priming' yourself.
There is an f77 I/O clean-up routine which you can call too (it's
not as important, though).  Without the 'priming', f77 I/O (at least
on pre-defined units) will have no effect.  A demonstration of the
the use of the priming and clean-up routines appears below.

Since f77 uses the C stdio library, you can mix C and f77 I/O by using
stdio in your C routines rather than straight Unix system calls.  Since
it may be difficult to predict which stdio file pointers are associated
with which f77 unit numbers, it's probably a good idea to stick with
'stdin', 'stdout' and 'stderr' when doing C I/O.

One other thing that is useful to have is a MAIN_() routine.  This is
normally created by f77 when it compiles the MAIN section of a program,
but if you replace the f77 main() with a C main(), it never gets
defined and f77 will complain about it if you use f77 to compile or
load your program.  (Yes, f77 will compile C files, one of its many
peculiar features.  Yes, this is useful because it means you can get
all of the f77 libraries without having to specify them explicitly, as
you would if you loaded your C and f77 objects 'by hand'.  Again, see
below for an example of this.)

Here's an example that demonstrates all of these features.  Put the
following code in a file 'c_main.c':

------------------------------------------------------------------------
# include	<stdio.h>

main( argc, argv, envp )
	int		argc;
	char		**argv;
	char		**envp;
{
	/*
	 * Process your arguments and environment here.
	 */

	/*
	 * Prime the f77 I/O routines, call MAIN_(), and clean up.
	 */
	f_init();
	MAIN_();
	f_exit();
	exit( 0 );
}

MAIN_()
{
	/*
	 * Call various f77 and C routines.
	 */
	c_routine();
	f77routine_();
}

c_routine()
{
	printf( "First some C I/O, then" );
}
------------------------------------------------------------------------

Put the following code in a file named 'f77_routines.f':

------------------------------------------------------------------------
	subroutine f77routine()

	print *, 'some f77 I/O.'

	return
	end
------------------------------------------------------------------------

Then compile the two files like this:

------------------------------------------------------------------------
% f77 c_main.c f77_routines.f -o cf
c_main.c:
f77_routines.f:
   f77routine:
%
------------------------------------------------------------------------

When you run the program, you get:

------------------------------------------------------------------------
% ./cf
First some C I/O, then  some f77 I/O.
%
------------------------------------------------------------------------

I hope this wasn't too complicated,

Donn Seeley    UCSD Chemistry Dept.       ucbvax!sdcsvax!sdchema!donn
32 52' 30"N 117 14' 25"W  (619) 452-4016  sdcsvax!sdchema!donn at nosc.ARPA



More information about the Comp.unix mailing list