我正在将我们的一些 Fortran 库代码转换为 C,以便我们最终拥有带有 Fortran 包装器的 C 函数。我们正在使用 Fortran 95。
处理可分配数组的首选方法是什么?
我可以将可分配数组传递给 C 函数并在 C 函数中对其进行 malloc 吗?(C 函数知道要分配的大小)
在 fortran 程序中,我可以取消分配在 C 函数中分配的东西吗?因此,最终客户端 fortran 应用程序要么释放数组,要么需要调用释放内存的 C 函数。
一个小例子或一个链接将不胜感激。
我正在将我们的一些 Fortran 库代码转换为 C,以便我们最终拥有带有 Fortran 包装器的 C 函数。我们正在使用 Fortran 95。
处理可分配数组的首选方法是什么?
我可以将可分配数组传递给 C 函数并在 C 函数中对其进行 malloc 吗?(C 函数知道要分配的大小)
在 fortran 程序中,我可以取消分配在 C 函数中分配的东西吗?因此,最终客户端 fortran 应用程序要么释放数组,要么需要调用释放内存的 C 函数。
一个小例子或一个链接将不胜感激。
在 Fortran 95 中,您不能将可分配数组作为可分配对象“传递”给任何东西,包括 Fortran 过程。
在 Fortran 2003 中,C 函数可以为数组分配存储空间,然后将其作为来自 ISO_C_BINDING 内部模块的 C_PTR 返回到 Fortran 端。然后可以使用 Fortran POINTER 和 ISO_C_BINDING 模块中的 C_F_POINTER 过程访问 C_PTR 指向的存储。
为了释放数组的存储空间,Fortran 端将再次调用 C 过程,传递 C_PTR,然后 C 函数在调用 free 时使用该 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 可分配变量。