Reputation: 163
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.
Upvotes: 2
Views: 133
Reputation: 2689
To complete the answer of @EricPostpischil, on the Fortran side the code should ideally define an explicit interface for the C function. And for if you really want to work on the array in the C function you should pass the 2 dimensions:
void c_func(int N, int M, double (*arr)[N])
interface
subroutine c_func(n,m,arr) bind(C,name="c_func")
integer(c_int), value :: n,m
real(c_double) :: a(n,m) ! a(n,*) or a(*) would also do
end subroutine c_func
end interface
...
real(c_double), dimension(:,:), allocatable :: a
integer :: n, m
...
allocate( a(n,m) )
...
call c_func( n, m, a )
...
Upvotes: 1
Reputation: 222272
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.
Upvotes: 3