cfortranfortran-iso-c-binding

passing an allocatable multi dimensional fortran array to a C function


I have the following main program in Fortran

program test
use iso_c_binding
implicit none

real(c_double), dimension(:,:), allocatable :: a

allocate(a(2,3))

call c_func(a)

print *,a

end program test

c_func is a function in C that takes in the multi dimensional array a and modifies it.

void c_func (double **arr) {
      modifies the array arr here
}

Is there a way to do this? I can do it for 1 dimensional allocatable array, but not for higher dimensions. And I don't want to flatten the array.


Solution

  • In C, double **arr does not declare a multidimensional array. It declares, at best, a pointer to an array of pointers to double. (Technically, it declares a pointer to one pointer to double, and it is common to put multiple pointers one after the other, making an array of pointers, so arr would be a pointer to the first element of an array of pointers to double.)

    Due to C semantics, such a pointer can be used in source code with two subscripts like a multidimensional array, as in arr[i][j], but the layout in memory is very different. arr points to memory where there are pointers, not memory where there are many double values laid out in rows and columns.

    To declare a pointer to (the start of) a multidimensional array, use double (*arr)[N], where N is the number of columns (in the C view) of the array. You may need to pass N to the function in an earlier parameter, unless it is a fixed value. The function declaration could be void c_func(size_t N, double (*arr)[N]). You might need to change size_t there to match the type the Fortran code is passing.