将可分配数组从fortran传递给C和malloc它

时间:2013-10-02 22:17:34

标签: c fortran fortran-iso-c-binding

我正在将一些Fortran库代码转换为C,以便我们最终拥有带有Fortran包装器的C函数。我们正在使用Fortran 95。

处理可分配数组的首选方法是什么?

  1. 我可以将可分配的数组传递给C函数并在C函数内对其进行malloc吗? (C函数知道要进行malloc的大小)

  2. 在fortran程序中,我可以解除在C函数中使用malloced的东西吗? 所以最后客户端fortran应用程序释放数组或者需要调用一个释放内存的C函数。

  3. 一个小例子或一个链接将受到高度赞赏。

1 个答案:

答案 0 :(得分:5)

在Fortran 95中,你不能将可分配数组“传递”为可分配的东西,包括Fortran程序。

在Fortran 2003中,C函数可以为数组进行malloc存储,然后将其作为C_PTR从ISO_C_BINDING内部模块返回到Fortran端。然后可以使用Fortran POINTER和ISO_C_BINDING模块中的C_F_POINTER过程访问C_PTR指向的存储。

为了释放数组的存储空间,Fortran端将再次调用C程序,传递C_PTR,C函数随后在调用中使用C_PTR。

#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可分配变量。