[net.unix] Calling f77 routines from C: HELP!

jwp@uwmacc.UUCP (Jeffrey W Percival) (01/25/86)

This applies to 4.2BSD and Ultrix-32M v1.1:

I am trying to call a f77 subroutine from a C program,
and I find that the supposedly "preconnected" i/o units 5 and 6
are not connected.  That is, when I do a simple print in the
Fortran subroutine, like:

	print *, 'hi!'

I get an entry in a file called fort.6.  What makes this especially
unfortunate, is that this works fine in 2.8BSD, and we have found that
the C/f77 programs that we wrote under 2.8BSD are failing to run
as expected under Ultrix (for the reason just described).

Is there a way to preserve the "preconnections" advertised in the
f77 documentation?

I would very much appreciate any comments you can make on this.  Thanks!
-- 
	Jeff Percival ...!uwvax!uwmacc!jwp

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (01/26/86)

> I am trying to call a f77 subroutine from a C program,
> and I find that the supposedly "preconnected" i/o units 5 and 6
> are not connected.  That is, when I do a simple print in the
> Fortran subroutine, like:
> 
> 	print *, 'hi!'
> 
> I get an entry in a file called fort.6.  What makes this especially
> unfortunate, is that this works fine in 2.8BSD, and we have found that
> the C/f77 programs that we wrote under 2.8BSD are failing to run
> as expected under Ultrix (for the reason just described).
> 
> Is there a way to preserve the "preconnections" advertised in the
> f77 documentation?

In general, it is unwise to mix C and Fortran unless the main
module is Fortran, and even then there are restrictions on
what is safe to do with respect to I/O.  This is due to the
need to set up Fortran I/O for the run-time system before
doing any Fortran I/O; this is normally done for you in the
Fortran start-off module.  You can try doing it "by hand" by
calling the function f_init(); some "f77" implementations
(e.g., SVR2) keep track of whether or not initialization has
been done and do it automatically if necessary.

jdz@wucec2.UUCP (Jason D. Zions) (01/27/86)

The "preconnection" of units 5 and6 is done by the f77 runtime startup.
This runtime statup routine is NOT included if you use a C main and link
with the cc command.

If you call your C main routine MAIN_(argc,argv,...) and do your final
linking with f77, things should work better. The approach I took was to write
a trivial f77 main program which called the real main (written in C).
-- 
Jason D. Zions				jdz@wucec2
Center for Engineering Computing	...!{seismo,cbosgd,ihnp4}
Washington University in St. Louis			!wucs!wucec2!jdz
Party of the first part disclaims any and all claims made by said party.

wyatt@cfa.UUCP (Bill Wyatt) (01/27/86)

> This applies to 4.2BSD and Ultrix-32M v1.1:
> 
> I am trying to call a f77 subroutine from a C program,
> and I find that the supposedly "preconnected" i/o units 5 and 6
> are not connected.  That is, when I do a simple print in the
> Fortran subroutine, like:
> 
> 	print *, 'hi!'
> 
> I get an entry in a file called fort.6. [...]
> > 	Jeff Percival ...!uwvax!uwmacc!jwp


This sounds very much like something Donn Seeley helped people with a while
back. I'll repost some of his original article:


>From donn@utah-gr.UUCP (Donn Seeley) Sun Feb  6 01:28:16 206
>Subject: Re: C calls FORTRAN subroutine
>Message-ID: <1207@utah-gr.UUCP>
>Date: Fri, 12-Oct-84 22:34:17 EDT
>
>>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@nosc.ARPA

BTW, the above is *not* Donn's current net address (see first lines of this
posting).

-- 

Bill    UUCP:  {seismo|ihnp4|cmcl2}!harvard!talcott!cfa!wyatt
Wyatt   ARPA:  wyatt%cfa.UUCP@harvard.HARVARD.EDU