Calling a FORTRAN subroutine from C

前端 未结 3 1958
刺人心
刺人心 2020-11-27 17:00

I am trying to call a FORTRAN function from C

My questions are:

  1. If fortRoutine is the name of my fortran subroutine, then I am calling

3条回答
  •  囚心锁ツ
    2020-11-27 17:44

    The way to do this now is to use the Fortran ISO C Binding on the Fortran side. This is part of the Fortran 2003 language standard and is available in many compilers; it is not specific to gcc. It has been described in many answers on this site. As part of the language standard, it is compiler and platform independent. And you do not need to know about the internal passing conventions of the compiler. The ISO C Binding, when used in the declaration of a Fortran subroutine or function, causes the Fortran compiler to use the C calling conventions so that that procedure can be directly called from C. You do not need to add hidden arguments or name mangle the Fortran subroutine name, i.e., no underscores. The name used by the linker comes from the "bind" option.

    Strings are a difficult case because technically in C they are arrays of characters and you have to match this in the Fortran. You also have to deal with the different definitions of strings: C is null terminated, Fortran fixed length and padded with blanks. The example shows how this works. Numbers are easier. The only issue with arrays is that C is row-major and Fortran column-major so that multi-dimensional arrays are transposed.

    int main ( void ) {
    
       char test [10] = "abcd";
    
       myfortsub (test);
    
       return 0;
    
    }
    

    and

    subroutine myfortsub ( input_string ) bind ( C, name="myfortsub" )
    
       use iso_c_binding, only: C_CHAR, c_null_char
       implicit none
    
       character (kind=c_char, len=1), dimension (10), intent (in) :: input_string
       character (len=10) :: regular_string
       integer :: i
    
       regular_string = " "
       loop_string: do i=1, 10
          if ( input_string (i) == c_null_char ) then
             exit loop_string
          else
             regular_string (i:i) = input_string (i)
          end if
       end do loop_string
    
       write (*, *) ">", trim (regular_string), "<", len_trim (regular_string)
    
       return
    
    end subroutine myfortsub
    

    You compile the C to an object file and use gfortran to compile the fortran and link both:

    gcc-mp-4.6   \
             -c  \
             test_fortsub.c
    
    gfortran-mp-4.6   \
         test_fortsub.o  \
         myfortsub.f90  \
         -o test_fortsub.exe
    

    Output is:

     >abcd<           4
    

提交回复
热议问题