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