How to convert a C-utility into a subroutine and call it from gfortran?

Tobias Burnus burnus@net-b.de
Tue Jun 19 12:16:00 GMT 2007


Hi Arjan,

I think you will have the following problem: You need to allocate the
array in C and arrays are quite differently organized in C and Fortran.
In C the array is only a chunk of data whereas in Fortran an array has
also upper/lower bounds, strides etc.

I see two relatively simple solutions:

a) The size of the array is known (at run time or compile time): simply
pass the arrays from fortran

b) Use two steps:
- determine the size needed for the array
- allocate the array in Fortran
- pass that allocated array to C

The complicated solution is to use Fortran 2003 and ISO C bindings, i.e.
something like the following (untested). gfortran 4.3 does not support
this yet; you would need to use the gfortran from the
Fortran-Experiments branch.

program ctest
  use iso_c_binding, only: c_float, c_int, c_ptr, c_null_char, C_F_POINTER
  implicit none
  interface
    function test(file, nx, ny, ptrarray) bind(c, name="test")
       use iso_c_binding
       integer(c_int)              :: test
       character(kind=c_char), dimension(*), intent(in) :: file
       integer(c_int), intent(out) :: nx, ny
       type(c_ptr), intent(out)    ::  ptrarray
    end function test
  end interface
  integer :: i
  integer(c_int) :: result, nx, ny
  real(c_float), pointer  :: array(:,:)
  type(c_ptr) ::  ptrarray
  nullify(array)
  ! result = test("MyFile"//c_null_char, nx, ny, ptrarray)
  ! This does not work yet with gfortran, use the following instead:
  result = test(['M','y','F','i','l','e',c_null_char], nx, ny, ptrarray)
  if(result /=0) stop 'ERROR'
  call C_F_POINTER(ptrarray, array, [ny, nx])


Tobias



More information about the Fortran mailing list