Frage

I am converting some of our Fortran library code into C so that we finally have C functions with Fortran wrappers around it. We are using Fortran 95.

What is the preferred way to handle allocatable arrays?

  1. Can I pass an allocatable array to a C function and malloc it inside the C function? (The C function knows the size to be malloc'ed)

  2. In the fortran program, can I deallocate something that was malloced in a C function? So finally either the client fortran application deallocates the array or is required to call a C function that frees the memory.

A small example or a link to one would be highly appreciated.

War es hilfreich?

Lösung

In Fortran 95 you can't "pass" allocatable arrays as an allocatable thing to anything, including Fortran procedures.

In Fortran 2003, the C function can malloc storage for the array, and then return that to the Fortran side as a C_PTR from the ISO_C_BINDING intrinsic module. The storage pointed to by the C_PTR can then be accessed using a Fortran POINTER and the C_F_POINTER procedure from the ISO_C_BINDING module.

To free the storage for the array, the Fortran side would again call into a C procedure, passing the C_PTR, which the C function then uses in a call to free.

#include "stdlib.h"
int *create_storage()
{
   /* Array of four integers. */
   return malloc(sizeof(int) * 4);
}

void destroy_storage(int *ptr)
{
   free(ptr);
}


PROGRAM fortran_side
  USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_F_POINTER, C_INT
  IMPLICIT NONE
  INTERFACE
    FUNCTION create_storage() BIND(C, NAME='create_storage')
      USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
      IMPLICIT NONE
      TYPE(C_PTR) :: create_storage
    END FUNCTION create_storage
    SUBROUTINE destroy_storage(p) BIND(C, NAME='destroy_storage')
      USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
      IMPLICIT NONE
      TYPE(C_PTR), INTENT(IN), VALUE :: p
    END SUBROUTINE destroy_storage
  END INTERFACE
  TYPE(C_PTR) :: p
  INTEGER(C_INT), POINTER :: array(:)
  !****
  p = create_storage()
  CALL C_F_POINTER(p, array, [4])   ! 4 is the array size.
  ! Work with array...
  CALL destroy_storage(p)
END PROGRAM fortran_side

In Fortran 201X, C header files and functions may be provided to allow C to work directly with Fortran allocatable variables.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top