\"Vladimír Fuka <\"name.surname at <mffDOTcuniDOTcz">> wrote:
> Hello, I have a problem with a generic interface and C binding, as
> demonstrated in a following program. I am receiving compile time error in
> the second call. As I understand it, it is because of the assumed size
> array. Is there any way to fix it? (At least because of theoretical
> reasons, I can live without the generic interface.)
Assumes size array should be fine.
> "ge.f90", Line = 37, Column = 6: ERROR: Incorrect argument rank in generic
> procedure call "FFTW_PLAN_GEN"
(snip)
> Error: There is no specific function for the generic 'fftw_plan_gen' at (1)
(snip)
> interface fftw_plan_gen
(snip of 1D case)
> type(C_PTR) function fftw_plan_r2r_2d(n0,n1,in,out,kind0,kind1,flags)
> bind(C, name='fftw_plan_r2r_2d')
> import
> integer(C_INT), value :: n0
> integer(C_INT), value :: n1
> real(C_DOUBLE), dimension(*), intent(out) :: in
> real(C_DOUBLE), dimension(*), intent(out) :: out
> integer(C_FFTW_R2R_KIND), value :: kind0
> integer(C_FFTW_R2R_KIND), value :: kind1
> integer(C_INT), value :: flags
> end function fftw_plan_r2r_2d
> end interface fftw_plan_gen
> type(c_ptr) :: p
> real(c_double), dimension(1,1) :: a
Yes, the 2D array a won't match the dimension(*) array, even
though it is legal for an assumed size array.
Exactly what Fortran does with assumed size isn't so obvious,
but the usual implementation passes the address of the first element.
If you instead dimension(1,*) or, as you note later (n0,*), then
it should work.
I am not sure if you can get away with two different ones with
the same name and different rank inside the generic. (In case
you want to allow either 1D or 2D passed to fftw_plan_r2r_2d.)
More likely, though, you can give them different names, but the
same bind(name='name') and it will allow it through.
> p= fftw_plan_r2r_2d(1_c_int,1_c_int, a, a, 0_c_int32_t, 0_c_int32_t,
> 0_c_int)
> p= fftw_plan_gen(1_c_int,1_c_int, a, a, 0_c_int32_t, 0_c_int32_t,
> 0_c_int)
Another possibility is to pass a c_ptr to the function, and put
c_loc(a) for each array argument. That is assuming that you don't
want it to select the generic based on rank.
-- glen