0 Replies Latest reply on Sep 14, 2013 11:54 AM by jiriwiesner

    calling Fortran from C, c_f_pointer does not create an array of derived type

    jiriwiesner

      Dear Developers,

      I have difficulty in using the C bindings when Fortran functions are called from C. My Fortran subroutines use non-interoperable types. If such a subroutine is to be called from C, the C code must be provided with a "handle" - the address of the first element of a non-interoperable structure. This address is used by further function calls to refer to the data structure and the Fortran code calls the c_f_pointer subroutine to convert the address to a Fortran pointer. The problem is that, in my code, I am not able to recover the Fortran pointer from the address of type(c_ptr). A simple test case is attached. This test case can be compiled and works under the GNU compiler. x86 Open64 4.5.2.1 fails to produce code that could be executed for array sizes greater that 1 (such a test command reads: ./a.out 2).

      I use my own build of x86 Open64 on 64bit Debian 7.1 Wheezy. The issue is reproducible under Debian 6.0.7 Squeeze with the rhel10 binaries provided by AMD. I have also seen the same failure under Open64 5.0.

       

      Further details:

        The non-interoperable type is an "array of pointers":

      type ptr_array

        type(chain), pointer :: ptr => null()   

      end type ptr_array             

       

      type chain                

        type(chain), pointer :: next

        integer v             

      end type chain              

       

      Code that seems to be the source of the failure (I hope I'm not mistaken) :

      subroutine array_add(array_p, as) bind(c)

        !     ... dummy variables    

        type(c_ptr), intent(IN), value :: array_p

        integer(c_int), intent(IN), value :: as

       

        ! ... local variables

        type(ptr_array), dimension(:), pointer :: array

       

        if (c_associated(array_p)) then

          call c_f_pointer(array_p, array, (/ as /))                                     

        else                                                                              

          print *, "array_p is NULL"                                                      

        end if

       

      Thank you for your help,

      Jiri