Передача выделяемого массива из fortran в C и malloc его

Я конвертирую часть кода нашей библиотеки Fortran в C, чтобы у нас наконец были функции C с оболочками Fortran. Мы используем Fortran 95.

Каков предпочтительный способ обработки размещаемых массивов?

  1. Могу ли я передать выделяемый массив в функцию C и выделить его внутри функции C? (Функция C знает размер, который нужно изменить)

  2. Могу ли я в программе fortran освободить то, что было нарушено в функции C? Итак, наконец, либо клиентское приложение fortran освобождает массив, либо требуется вызвать функцию C, которая освобождает память.

Мы были бы очень признательны за небольшой пример или ссылку на него.


person jitihsk    schedule 02.10.2013    source источник
comment
Выделяемые массивы и указатели на хранилище от malloc принципиально отличаются. Фортран allocate делает гораздо больше, чем просто вызов malloc.   -  person Vladimir F    schedule 03.10.2013


Ответы (1)


В Fortran 95 вы не можете «передавать» размещаемые массивы как размещаемые объекты чему-либо, включая процедуры Fortran.

В Fortran 2003 функция C может выделить память для массива, а затем вернуть это на сторону Fortran как C_PTR из внутреннего модуля ISO_C_BINDING. Затем к хранилищу, на которое указывает C_PTR, можно получить доступ с помощью Fortran POINTER и процедуры C_F_POINTER из модуля ISO_C_BINDING.

Чтобы освободить хранилище для массива, сторона Fortran снова вызовет процедуру C, передав C_PTR, который функция C затем использует в вызове для освобождения.

#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

В Fortran 201X могут быть предусмотрены файлы заголовков C и функции, позволяющие C работать напрямую с назначаемыми переменными Fortran.

person IanH    schedule 02.10.2013