home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / lang / c / 20066 < prev    next >
Encoding:
Internet Message Format  |  1993-01-22  |  5.0 KB

  1. Xref: sparky comp.lang.c:20066 comp.lang.fortran:5123
  2. Newsgroups: comp.lang.c,comp.lang.fortran
  3. Path: sparky!uunet!usc!sol.ctr.columbia.edu!phoenix!bobp
  4. From: bobp@msi.com (Bob Pitha)
  5. Subject: Re: calling a Fortran subroutine from a C program
  6. Followup-To: comp.lang.c,comp.lang.fortran
  7. References: <1jmqdaINN11g@mudhoney.mathcs.emory.edu>
  8. Sender: nobody@ctr.columbia.edu
  9. Organization: Molecular Simulations, Inc.
  10. Date: Fri, 22 Jan 1993 13:07:43 GMT
  11. X-Newsreader: TIN [version 1.1 PL8]
  12. Message-ID: <1993Jan22.130743.27130@sol.ctr.columbia.edu>
  13. X-Posted-From: phoenix.msi.com
  14. NNTP-Posting-Host: sol.ctr.columbia.edu
  15. Lines: 114
  16.  
  17. Scott White (swhite@mathcs.emory.edu) wrote:
  18. : Can someone please tell me how to call a Fortran subroutine from a C program?
  19. : The environment is sun4, OS 4.1.2.
  20.  
  21. Sure, this isn't really that hard as long as you keep a few basic issues in
  22. mind:
  23.  
  24. 1) Function names: Fortran is a case-insensitive language, so typically
  25.  Fortran compilers convert names to entirely upper- or lower-case.  The
  26.  sun compiler does lowercase; it also appends an underscore to the end
  27.  of the function name.  Thus, a Fortran subroutine named MyFortranSub
  28.  would be exported to the linker as myfortransub_.  There is an option
  29.  for the compiler to preserve case, I think it's -U, but I'll assume
  30.  you're not using it.
  31.  
  32. 2) Arguments: Fortran always expects pointers in its argument list.  So
  33.  always pass an address from C.
  34.  
  35. 3) Arrays: There are a couple of insidious issues with arrays: first,
  36.  remember that C arrays start from 0, and Fortran from 1.  So if you
  37.  assign a value in C to element [3], you should access it in the Fortran
  38.  subroutine as element (4).  Alternately, declare your arrays in Fortran
  39.  to explicitly start from 0.  I don't like to do that, but you can inf
  40.  you want.
  41.    Multi-dimensional arrays can be a headache, too, because it's easy to
  42.  get the order of the subscripts mixed up.  C arrays are stored such that
  43.  the second subscript varies faster than the first: x[2][2] is stored in
  44.  memory in the following order: x[0][0]; x[0][1]; x[1][0]; x[1][1].  It's
  45.  exactly the opposite in Fortran; the array x (2,2) is stored as: x(1,1);
  46.  x(2,1); x(1,2); x(2,2).  So remember to reverse the order of your
  47.  subscripts when accessing multidimenstional arrays.
  48.  
  49. 4) Character arrays: For each character array in the argument list, there
  50.  should be a long int at the end of the argument list specifying the
  51.  *declared* length of the array - that is, how much space is allocated
  52.  for it.  Since Fortran blank-fills character arrays, this number will
  53.  specify how many places to fill.  If you have more than one character
  54.  array in the argument list, the length arguments should be in the same
  55.  order as the character arguments.
  56.  
  57.   So now, here's a mocked-up example of how to do this.  I'll try to keep
  58. it short but still touch on each concept to some extent:
  59.  
  60.   (in C):
  61.  
  62.     int      int_arg;
  63.     int      int_array [3];
  64.     int      int_matrix [4][3];
  65.     float    float_arg;
  66.     char     string [12];
  67.  
  68.     strcpy (string, "test");
  69.     int_array [1] = 37;
  70.     int_matrix [2][1] = 54;
  71.     myfortransub_ (&int_arg, &float_arg, int_array, int_matrix, string,
  72.                    (long) strlen (string));
  73.  
  74.  
  75.  (and now the Fortran part)
  76.  
  77.       subroutine MyFortranSub (int_arg, float_arg, int_array,
  78.      +                         int_matrix, string)
  79.       integer       int_arg
  80.       real          float_arg
  81.       integer       int_array (3)
  82.       integer       int_matrix (3, 4)
  83.       character*(*) string
  84.  
  85.       int_array (2) should be 37
  86.       int_matrix (2, 3) should be 54
  87.       string should be "test"
  88.  
  89. : Also, the called Fortran routine takes variables which are arrays as 
  90. : parameters.  And, I looked and saw that the subscripts start at 1, whereas in
  91. : C they start at zero.  That's no problem is it (an address is an address):
  92.  
  93.  No, it's no problem, assuming you remember it everywhere.  It only makes
  94. it a bit easier to make one of those annoying off-by-one subscript errors!
  95.  
  96. : /* .c file */
  97. :     int num[100];
  98. :     double zeta[100];
  99.  
  100. :     foo(num, zeta);
  101.  
  102.  
  103. : /* .f file */
  104. :     subroutine foo(number, gamma)
  105. :     integer*4 number(100)
  106. :     real*8    gamma(100)
  107.  
  108. :     /* program proceeds to manipulate values in the arrays, with subscripts
  109. :         1 through 100, not 0 through 99 */
  110.  
  111.   As said above, in your C file you should call foo_, not foo.
  112.  
  113. : Finally, if the Fortran subroutine changes the values in gamma, the changes
  114. : show up when we return to the C program, right?
  115.  
  116.   Absolutely.  In both the C function and the Fortran subroutine, gamma
  117. refers to the same 400 bytes of memory.
  118.  
  119.   There's a section in the Sun FORTRAN User's Guide that talks about
  120. C/Fortran interfaces.  If you have the manual, it's worth reading.  There
  121. are a lot of little picky issues I didn't touch on - and probably won't
  122. come up if you're doing something as simple as the foo function you use
  123. as an example.
  124.  
  125.   Good luck!
  126.  
  127. -----------------------------------------------------------------------
  128. Bob Pitha                      Molecular Simulations Inc.
  129. bobp@msi.com                   16 New England Executive Park
  130. (617) 229-9800 x242            Burlington, MA 01803-5297
  131.