1

after a lot of searching, I decided to post my question.

I have to pass some arrays (1D and 2D) to IDL to my fortran routines (I'm a "modern fortran" programmer). IDL is a column major language, and I have all the arrays already allocated before calling the fortran subroutine.

The problem is that IDL can pass anything to C functions, although some non-standard way to pass arrays to fortran are viable (e.g. http://132.248.1.102/~morisset/idl_cours/IDL/fortran.htm ). All array and structure arguments are passed by reference with the IDL function CALL_EXTERNAL (http://www.exelisvis.com/docs/CALL_EXTERNAL.html)

I'm looking for a fortran wrapper that uses the ISO_C_BINDINGS to handle the 1D and 2D arrays.My fortran subroutine has the same interface as the following one (the math is a little bit complicated)

MODULE test
IMPLICIT NONE
CONTAINS
PURE SUBROUTINE fortran_sub_array(x1a,x2a,ya,x1,x2,y_out)
  IMPLICIT NONE
  REAL, DIMENSION(:), INTENT(IN) :: x1a,x2a, x1,x2
  REAL, DIMENSION(:,:), INTENT(IN) :: ya
  REAL, DIMENSION(:,:), INTENT(INOUT) :: y_out
  INTEGER :: dim1, dim2, ii, jj

  dim1 = size(y_out,1)
  dim2 = size(y_out,2)

   do jj=1, dim2
    do ii=1, dim1
     y_out(ii,jj)= 0. !actually some functions...
    enddo
   enddo

  END SUBROUTINE
  ENDMODULE

I have found a lot of good answers, but I'm looking for a standard way to pass 2D arrays. I don't have to allocate or deallocate the y_out array, just fill it with values. All the checks on the arrays dimensions are alredy done in IDL before calling the fortran_sub_array.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
andrea
  • 151
  • 1
  • 8

1 Answers1

0

Your problem are the assumed shape arrays. You will have to change your Fortran subroutine, or write a wrapper:

  subroutine wrapper(dim1, dim2, x1a,x2a, ya, x1, x2, y_out) bind(C, name="...")
    integer(c_int), value :: dim1, dim2
    REAL(c_float), DIMENSION(dim1), INTENT(IN) :: x1a x1
    REAL(c_float), DIMENSION(dim2), INTENT(IN) :: x2a, x2
    REAL(c_float), DIMENSION(dim1,dim2), INTENT(IN) :: ya
    REAL(c_float), DIMENSION(dim1,dim2), INTENT(INOUT) :: y_out

    call fortran_sub_array(x1a,x2a,ya,x1,x2,y_out)
  end subroutine

Adjust the bounds as appropriate, I had to guess. The C side is very straightforward, just the two bounds and the pointers.