我正在将一些Fortran库代码转换为C,以便我们最终拥有带有Fortran包装器的C函数。我们正在使用Fortran 95。
处理可分配数组的首选方法是什么?
我可以将可分配的数组传递给C函数并在C函数内对其进行malloc吗? (C函数知道要进行malloc的大小)
在fortran程序中,我可以解除在C函数中使用malloced的东西吗? 所以最后客户端fortran应用程序释放数组或者需要调用一个释放内存的C函数。
一个小例子或一个链接将受到高度赞赏。
答案 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可分配变量。