fortran pass character*81 array to c/c++ code

前端 未结 2 2053
独厮守ぢ
独厮守ぢ 2021-01-28 09:58

I am a fresh in programming, I wanna to call a fortran function in my c++ code. the thing is I dont know how to pass a fortran character*81 array to my c++.

fortran code

相关标签:
2条回答
  • 2021-01-28 10:42

    The following code seems to work for gcc4 on Linux(x86_64), but it is not clear whether it is also valid for other platforms. (As suggested above, C-interoperability of modern Fortran may be useful.)

    func01.f90

    subroutine func01( a )
        character(*) :: a( 2 )
        print *
        print *, "char length = ", len(a(1)), len(a(2))
        print *, "raw a(1) : [", a(1), "]"
        print *, "raw a(2) : [", a(2), "]"
        print *, "trim     : [", trim(a(1)), "] [", trim(a(2)), "]"
    end
    

    main.cpp

    extern "C" {
        void func01_( char *c, const int len );
    }
    
    #include <iostream>
    #include <cstring>  // for memset()
    int main()
    {
        const int lenmax = 30, numstr = 3; // changed char length to 30 to fit in the terminal
        char a[ numstr ][ lenmax ];
        std::string str[ numstr ];
    
        str[0] = "moon"; str[1] = "mercury"; str[2] = "jupiter";
    
        for( int k = 0; k < numstr; k++ ) {
            memset( a[k], ' ', lenmax );  // fill space                                              
            str[k].copy( a[k], lenmax );  // copy at most lenmax char (no \0 attached)                        
        }
    
        func01_( a[0], lenmax );
        func01_( a[1], lenmax ); // pass from mercury
        return 0;
    }
    

    Compile

    $ g++ func01.f90 main.cpp -lgfortran
    

    Result

    char length =           30          30
    raw a(1) : [moon                          ]
    raw a(2) : [mercury                       ]
    trim     : [moon] [mercury]
    
    char length =           30          30
    raw a(1) : [mercury                       ]
    raw a(2) : [jupiter                       ]
    trim     : [mercury] [jupiter]
    
    0 讨论(0)
  • 2021-01-28 10:49

    Here is a portable solution to pass an array of arbitrary length strings from C to Fortran.

    I used a C++ file very similar to your own:

    #include <iostream>
    
    extern "C" void func01(const char **a);
    
    int main()
    {
      const char *a[2] = {"Hello World","This is a test"};
      func01(a);
      return 0;
    }
    

    The only changes above are the initialization of the character arrays and removing the not-so-portable underscoring of the Fortran function. Instead we will be using standard C interoperability provided by Fortran 2003. The Fortran implementation of func01 becomes:

    subroutine func01(cstrings) bind(C,name="func01")
      use, intrinsic :: iso_c_binding, only: c_ptr, c_char, c_f_pointer
      implicit none
      type(c_ptr), dimension(2), target, intent(in) :: cstrings
      character(kind=c_char), pointer :: a1(:), a2(:)
    
      ! size_t strlen(char * s);
      interface
         function strlen(s) bind(C, name='strlen')
           use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t
           implicit none
           type(c_ptr), intent(in), value :: s
           integer(c_size_t) :: strlen
         end function strlen
      end interface
    
      call c_f_pointer(cstrings(1), a1, [strlen(cstrings(1))])
      call c_f_pointer(cstrings(2), a2, [strlen(cstrings(2))])
      write (*,*) a1
      write (*,*) a2
    end subroutine func01
    

    The bind attribute is what gives us interoperability with C for the function name and we are using C types for variables. The variable cstrings will take an array of 2 pointers, or in C, *[2] or **. The bulk of the procedure is an interface block which lets us call the standard C library routine strlen to make our life easier with the following calls to c_f_pointer which translates a C pointer to a Fortran pointer.

    When compiled and run, the output, as expected, is:

    $ ./string-array-test
     Hello World
     This is a test
    

    Compiled and tested with gcc 5.1.0.

    0 讨论(0)
提交回复
热议问题