I am trying to pass a single dimension array from a FORTRAN program to C.
The C function is called but the values that it holds are garbage. But whereas if I try ca
program test_Cfunc
use iso_c_binding
implicit none
interface
function test_func (a) bind (C, name="test_func")
import
integer (c_int) :: test_func
real (c_double), dimension (1:4), intent (in) :: a
end function test_func
end interface
real (c_double), dimension (1:4) :: a = [ 2.3, 3.4, 4.5, 5.6 ]
integer (c_int) :: result
result = test_func (a)
write (*, *) result
end program test_Cfunc
Using the Fortran's ISO C Binding, the solution is portable to pairs of compilers from the same vendor, or combinations supported by the vendor of the Fortran compiler. You don't have to understand the passing conventions of particular compilers, nor deal with name-mangling by the Fortran compiler (that is override by the name
clause of the bind
). You describe the C routine to Fortran with an interface
block, specifying C types with Fortran kind values provided in the ISO C Binding. There is a list of the kind types in the gfortran manual in the Chapter "Intrinsic Modules". Also see the Chapter "Mixed-Language Programming". Since the ISO C Binding is part of the language standard, this documentation is more general then just gfortran.
Passing arrays between Fortran and C is a non-trivial problem. The particular C and Fortran compilers matter.
The first problem I see is that you specify double
to match real*4
. That is certainly invalid on almost all platforms. Declare the C function as:
int test_func (float *a)
This could work on some platforms, though many Fortran compilers pass the address of an "array descriptor" and not the array itself. Check the documentation for the Fortran compiler.