Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site utah-gr.UUCP Path: utzoo!linus!philabs!cmcl2!seismo!utah-cs!utah-gr!donn From: donn@utah-gr.UUCP (Donn Seeley) Newsgroups: net.unix,net.lang.f77 Subject: Re: C calls FORTRAN subroutine Message-ID: <1207@utah-gr.UUCP> Date: Fri, 12-Oct-84 22:34:17 EDT Article-I.D.: utah-gr.1207 Posted: Fri Oct 12 22:34:17 1984 Date-Received: Sun, 14-Oct-84 04:49:05 EDT References: <249@imsvax.UUCP> <1206@hao.UUCP> Organization: CS Dept., University of Utah Lines: 119 Xref: utah-cs net.unix:2757 net.lang.f77:157 From the original article by Aldrin Leung: In the C program, I have ---------- #includemain() { 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 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