home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.lang.c:20038 comp.lang.fortran:5119
- Path: sparky!uunet!lhdsy1!kato.lahabra.chevron.com!hwrvo
- From: hwrvo@kato.lahabra.chevron.com (W.R. Volz)
- Newsgroups: comp.lang.c,comp.lang.fortran
- Subject: Re: calling a Fortran subroutine from a C program
- Message-ID: <9229@lhdsy1.lahabra.chevron.com>
- Date: 22 Jan 93 01:12:29 GMT
- References: <1jmqdaINN11g@mudhoney.mathcs.emory.edu>
- Sender: news@lhdsy1.lahabra.chevron.com
- Followup-To: comp.lang.c
- Organization: Chevron Oil Field Research Company
- Lines: 99
-
- In article <1jmqdaINN11g@mudhoney.mathcs.emory.edu>, swhite@mathcs.emory.edu (Scott White) writes:
- |> Can someone please tell me how to call a Fortran subroutine from a C program?
- |> The environment is sun4, OS 4.1.2.
- |>
- |> Also, the called Fortran routine takes variables which are arrays as
- |> parameters. And, I looked and saw that the subscripts start at 1, whereas in
- |> C they start at zero. That's no problem is it (an address is an address):
- That is correct, it doesn't matter where the arrays start in fortran but
- in C they sill always start at 0.
- |>
- |> /* .c file */
- |> int num[100];
- |> double zeta[100];
- |>
- |> foo(num, zeta);
- |>
- |>
- |> /* .f file */
- |> subroutine foo(number, gamma)
- |> integer*4 number(100)
- |> real*8 gamma(100)
- |>
- |> /* program proceeds to manipulate values in the arrays, with subscripts
- |> 1 through 100, not 0 through 99 */
- |>
- |>
- |> Finally, if the Fortran subroutine changes the values in gamma, the changes
- |> show up when we return to the C program, right?
- Yes.
- |>
- |> Your gracious help is deeply appreciated.
- |>
- Some other things to think about: If you wanted to pass the number of
- elements to process:
-
- int n = 100;
- foo(num,zeta,&n);
-
- subroutine foo(num,zeta,n)
- ...
- Note that fortran always expects the address of something, C (strickly
- speaking always passes things by the value of the somethings. If you didn't
- include the &n in the c call to foo, the fortran foo would look for the
- number of elements at addess 100 and probably abort on the call. This
- is sometimes difficult to track down.
-
- If you are passing character strings, all bets are off. It depends heavily
- on what fortran compiler you are using and how they handle character
- arrays. Sometimes the fortran arguement list is modified to include
- the length of the character string, so there may be extra arguments
- sometwhere in the list. What I did is to write a short fortran routine
- that expects a byte or integer*1 array:
-
- subroutine c_str_to_for(cstr,fstr)
- byte cstr(*)
- character*(*) fstr
- i = 1
- c set entire fortran string to blanks to handle shorter strings
- fstr = ' '
- c don't overflow the fortran string and loop until the c null characte appears.
- while(i .le. len(fstr).and.cstr(i) .ne. 0)
- c copy character and increment
- fstr(i:i) = char(cstr(i))
- i = i + 1
- end do
- c or some such thing. This may not be completely correct, it's from memory.
- return
-
- and use this to convert c strings to fortran strings.
- so
- char *cstr = "This is a C string";
- foo(str);
-
- subroutine foo(cstr)
- byte cstr(*)
- character*100 fstr
- c_str_to_for(cstr,fsrt);
- write(6,*) fstr
- return
- end
-
- Also some compilers change the name of the fortran routine as seen
- by the linker. The MIPS compiler is notorius for this. It adds an
- underscore on the end of the name and changes all characters in the
- name to lower case. So on that compiler you'd do foo_(cstr); instead..
-
- All in all, calling fortran from c and vice-versa can be a total bitch.
-
- Have fun.
- s
-
- --
-
- ======================
- Bill Volz
- Chevron Petroleum Technology Co.
- Earth Model/Interpretation & Analysis Division.
- P.O. Box 446, La Habra, CA 90633-0446
- Phone: (310) 694-9340 Fax: (310) 694-7063
-