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