将可分配数组从fortran传递给C并对其进行malloc [英] Passing allocatable array from fortran to C and malloc it

查看:17
本文介绍了将可分配数组从fortran传递给C并对其进行malloc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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. 我可以将一个可分配数组传递给一个 C 函数并在 C 函数中 malloc 吗?(C 函数知道要分配的大小)

  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)

在 fortran 程序中,我可以取消分配在 C 函数中分配的东西吗?所以最后要么是客户端 fortran 应用程序释放数组,要么需要调用一个释放内存的 C 函数.

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.

推荐答案

在 Fortran 95 中,您不能将可分配数组作为可分配对象传递"给任何东西,包括 Fortran 过程.

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

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

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.

为了释放数组的存储空间,Fortran 端将再次调用 C 过程,传递 C_PTR,然后 C 函数在调用 free 时使用该 C_PTR.

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

在 Fortran 201X 中,可以提供 C 头文件和函数以允许 C 直接使用 Fortran 可分配变量.

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

这篇关于将可分配数组从fortran传递给C并对其进行malloc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆