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
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
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.