Calling C subroutine from FORTRAN

Myron A. Calhoun mac at harris.cis.ksu.edu
Fri Nov 16 02:09:37 AEST 1990


In article <1990Nov14.191142.1016 at vax5.cit.cornell.edu> njzy at vax5.cit.cornell.edu (T. Joseph Lazio, Cornell University) writes:
>Keywords:  C subroutine, FORTRAN program, memory allocation
>      I am currently in the midst of converting a program from VMS
>      FORTRAN to UNIX FORTRAN.  The program needs to allocate memory.
>      In its VMS form, it uses the call LIB$GET_VM.  Unfortunately,
>      the only way to allocate memory on my UNIX machine is to use
>      the call to malloc, which requires some knowledge of C.

>      I have been working on this problem, on and off, for a number
>      of months now and have been rather unsuccessful in my attempts
>      to call a C subroutine from a FORTRAN program.  If anybody
>      else has figured out a way to do this, I would appreciate it
>      if you could get in touch with me via e-mail.  Thanks.

A recent posting pretty-well said it all
(but my elaboration follows anyway!-):

>Article 3585 of comp.lang.fortran:
>From: bron at bronze.wpd.sgi.com (Bron Campbell Nelson)
>Subject: Re: FORTRAN callable C functions to allocate/deallocate arrays.

>In article...., mlzerkle at athena.mit.edu (Michael L Zerkle) writes:
>> I am trying to develop C functions to allocate and deallocate arrays
>> for use in a FORTRAN progam....   [several lines deleted]

>I'll ... mention one way that....

    [MANY lines deleted]

>Some ...[systems]...  do not define a Fortran interface to
>malloc.  In such a case you'll also have to write the 1 line C routine

>        int malloc_(size) int *size; { return (int) malloc(*size); }
                   ^
NOTICE THE --------^------- UNDERLINE character!!!!!

On the Harris 4.2BSD system I'm on right now, there are several
so-called C routines that ARE included in the FORTRAN library:
"system" and "getc" for example.  "Malloc" is not.  One way to tell
this is to say "man nameofroutine", such as "man system", "man
getc", and "man malloc".  If the manual shows pages with an "F" in
the title, as ours does for "SYSTEM (3F)" and "GETC (3F)" but NOT
for malloc, then there IS a FORTRAN-callable version.  [Incidentally,
there seems to be a "bug" in the "man" display procedure on our
system; the "... (3F)" information is displayed and then IMMEDIATELY
OVERWRITTEN by the "... (3C)" information; no "MORE--" prompt is
given!  So you have to be fast on the ^S key to read it!]  For
example, I use the following little routine routinely to read one
character from stdin without needing a RETURN:

      SUBROUTINE GET1KY (Char)

c---- Get a single character without the necessity of a carriage return.

      CHARACTER Char*1
      INTEGER   GETC, Status

c---- Turn off buffering of input and character echo
      CALL SYSTEM ("stty cbreak -echo")

      Status = GETC (Char)

c---- Set TTY to 'normal' state
      CALL SYSTEM ("stty -cbreak echo")

c     GET1KY                          Myron A. Calhoun, 17X90
      END

(Ignore the capitalization; FORTRAN does!  I have my own "style" of
 coding FORTRAN statements to make some things "stick out" in an
 obvious way, partly 'cause I taught Modula-2 last semester and I
 liked the way the capitalized keywords looked on student papers!
 I've since converted many years worth of FORTRAN program to this
 style, and I still like it.)

Just to prove a point, I just added appropriate declarations and
the statements:

       Pointr = MALLOC (200)
       CALL FREE (Pointr)

to the above routine and recompiled and TRIED to link it.  The
linker gave me messages like this (from memory):

  "can't find _free_; link aborted"
  "can't find _malloc_; link aborted"
              ^    ^ ^
NOTICE THE ---^----^-^------- UNDERLINE characters!!!!!

This demonstrates that (our) f77 compiler adds underline characters
to the names of modules as it compiles them.  I conclude that one
can "convert" a C routine (if the source code is available) into a
FORTRAN-callable version by adding underline character(s)....

If one does NOT have the source code, then, as suggested by the
above-reposted article, one can create a new (and very short!) C
routine which 
  (a) (for convenience) has the same name as the original C routine
      PLUS AN EXTRA TRAILING UNDERLINE CHARACTER, and
  (b) essentially just invokes the original C routine within.

This is shown in the last line of the above-reposted article and
which I repeat here for convenience:

<        int malloc_(size) int *size; { return (int) malloc(*size); }
                   ^                                 ^^^^^^
NOTICE THE --------^------- UNDERLINE.      ORIGINAL ^^^^^^ C routine.

I tried it; it links.  (I haven't actually RUN my butchered-up
routine, but it compiled and linked just fine!)
--Myron.
--
# Myron A. Calhoun, Ph.D. E.E.; Associate Professor   (913) 539-4448 home
# INTERNET: mac at harris.cis.ksu.edu   (129.130.10.2)         532-6350 work
# UUCP: ...{rutgers, texbell}!ksuvax1!harry!mac             532-7353 fax
# AT&T Mail:  attmail!ksuvax1!mac



More information about the Comp.unix.questions mailing list