leung@imsvax.UUCP (Aldrin Leung) (10/12/84)
I have difficulty to use a C main program to call a Fortran
subroutine that have I/O and would like anybody have
related experience to give me some help. I usually don't
read mail under unix.wizard. Please send mail to me. The
following is what I did.
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
----------
I use "cc -c main.c", "f77 -c try.f", and
"cc main.o try.o -lF77 -lU77 -lI77"
No output like "subprogram" is printed.
Thanks in advance!
Aldrin Leung
...umcp-cs!eneevax!imsvax!leung or
...umcp-cs!cvl!elsie!leung
woods@hao.UUCP (Greg "Bucket" Woods) (10/13/84)
> 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 > ---------- > This is a weird one. I know why it doesn't work, but knowing why isn't much help. I put an "fflush(stdout)" call in the main program after the call to "try", and then ran "adb" on this program, putting a breakpoint in "write". The result of that shows that it is trying to write the string "subprogram" on file descriptor 3. How about it, compiler wizards? What the '&"#%@*! is going on? --Greg -- {ucbvax!hplabs | allegra!nbires | decvax!stcvax | harpo!seismo | ihnp4!stcvax} !hao!woods "...the bus came by, and I got on, that's when it all began..."
donn@utah-gr.UUCP (Donn Seeley) (10/13/84)
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
chris@umcp-cs.UUCP (Chris Torek) (10/13/84)
Doesn't the 4.2BSD f77 I/O library require a call to ``ioinit'' first? -- (This mind accidently left blank.) In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690 UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
mather@uicsl.UUCP (10/15/84)
I tried this little teaser of a program and nothing appears on stdout, however, a little file called fort.6 is generated with the contents: subprogram inside. Some not-too-well-known info: 1) opening a file with "open(unit=n)" creates a file "fort.n" unless ioinit has been used to change the default. ioinit(3F) claims that there is no automatic filename association for fortran logical units, but there is. In libI77, see err.c. 2) It is difficult to pass C file descriptors to f77 as unit #s and visa versa. 3) Opening a file as "open(unit=n,file='/dev/tty')" will put all output written on unit n to your tty. Impossible to separate standard output and standard error, however. I placed this open statement prior to the write and it worked, but this isn't good if you call this routine more than once, since it isn't nice to reopen a file if it is already open. It should be closed first. But closing, then opening puts the pointer at the beginning of the file (unless ioinit is used to make files appendable). Callling C from FORTRAN is nice, but going the other way is a real pain, especially since you have to include all of the libF77 and libI77 junk. Messy messy messy. b.c.mather software surgeon uiucdcs!uicsl!mather
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (10/16/84)
Exactly. The Fortran I/O system requires initialization, and a C main program will not do it by default.
root@uokmet.UUCP (10/22/84)
/***** uokmet:net.unix / uicsl!mather / 4:31 pm Oct 14, 1984 */ >>> Calling C from FORTRAN is nice, but going the other way is a real pain, >>> especially since you have to include all of the libF77 and libI77 junk. >>> Messy messy messy. There is a nice little trick that I've discovered of recent. If you have a C main program that calls FORTRAN routines, use "MAIN__()" instead of "main()", then compile with f77! The linking is done for you. There is documentation called "A Portable Fortran 77 Compiler" (found in "UNIX Programmers' Manual" Volume 2B, at least that's its location for 2BSD) that might also be of some use. Kevin W. Thomas Univ. of Oklahoma Norman, OK 73019 UUCP: ...!ctvax!uokvax!uokmet!kwthomas
leiby@masscomp.UUCP (10/22/84)
Regarding the fellow who calls a FORTRAN subroutine from his C program and is then unable to do I/O from within the FORTRAN subroutine: The problem here is that the FORTRAN start-up code maps logical unit numbers to Unix(tm) file descriptors in an implementation dependent way. Since the main program is in C, none of this setup gets done. Thus when the FORTRAN I/O library call is executed, it can't find a valid logical unit number table, and the output (if any) is trashed. I'd be amazed if the fellow gets any output at all. A solution? Unless you have the compiler code to look at, I'm afraid it's like the old joke: Patient: Dr., it hurts when I do this. Doctor: Well, don't do that!!! Mike Leibensperger {decvax,ihnp4,harpo,tektronix}!masscomp!leiby -- Mike Leibensperger {decvax,tektronix,harpo}!masscomp!leiby Masscomp; One Technology Park; Westford MA 01886
joels@tektronix.UUCP (Joel Swank) (10/31/84)
> Regarding the fellow who calls a FORTRAN subroutine from his C > program and is then unable to do I/O from within the FORTRAN > subroutine: > > The problem here is that the FORTRAN start-up code maps logical > unit numbers to Unix(tm) file descriptors in an implementation > dependent way. Since the main program is in C, none of this > setup gets done. Thus when the FORTRAN I/O library call is > executed, it can't find a valid logical unit number table, > and the output (if any) is trashed. I'd be amazed if the fellow > gets any output at all. > > A solution? Unless you have the compiler code to look at, I'm > afraid it's like the old joke: > I had this problem under 4.2bsd and I found that output was going to a file called fort.6. I circumvented the problem using a symbolic link: ln -s /dev/tty fort.6 Just execute this command before running the program, and output will go to the terminal. Joel Swank Software Center Tools Support 50-487 Tektronix Beaverton OR 97077 (503) 627-4403