正如answer by IanH 所说,
技术规范 TS 29113 允许在 C 函数中执行 Fortran 可分配对象的分配,这对 Fortran 方面具有持久影响。
由于较早的答案是书面的,因此对此 TS 的支持有所增加(尽管它仍然不大,并且我们将在此答案中使用的 C 描述符部分明显不受当前 gfortran 的支持)。这意味着现在可能值得写一个例子。此示例在 Fortran 2008 下无效。
我们考虑由CFI_desc_t(来自源文件ISO_Fortran_binding.h)和C 函数CFI_allocate 给出的C 结构。
假设我们对 rank-3 数组的分配发生在与以下 Fortran 接口兼容的 C 过程中
interface
subroutine allocating_sub(x) bind(c)
use, intrinsic :: iso_c_binding, only : c_float
real(c_float), allocatable :: x(:,:,:)
end subroutine allocating_sub
end interface
我们注意到这样的 Fortran 接口与 C 函数原型兼容,该原型具有作为指向 CFI_cdesc_t 的指针的形式参数。
将此 C 函数定义为(带有幻数,并且缺少很多
其他合理的检查等):
#include "ISO_Fortran_binding.h"
void allocating_sub(CFI_cdesc_t* x) {
if (x->base_addr) CFI_deallocate(x);
CFI_index_t lower[3]={-1, 5, 1};
CFI_index_t upper[3]={20, 9, 5};
CFI_allocate(x, lower, upper, 0);
}
CFI_index_t 是“能够表示两个指针相减结果的标准有符号整数类型的 typedef 名称”。
分配发生在CFI_allocate 函数中,该函数在这里分配x,其下限和上限由明显的变量给出。在我们的例子中,最后一个数字 (0) 被忽略,x 不对应于 Fortran 字符类型。
为了完成这个例子,使用 Fortran 程序:
use, intrinsic :: iso_c_binding, only : c_float
implicit none
interface
subroutine allocating_sub(x) bind(c)
import c_float
real(c_float), allocatable :: x(:,:,:)
end subroutine allocating_sub
end interface
integer i
real(c_float), allocatable :: x(:,:,:)
allocate(x(6,2,5))
print 1, (LBOUND(x,i), UBOUND(x,i), i=1,3)
call allocating_sub(x)
if (allocated(x)) print 1, (LBOUND(x,i), UBOUND(x,i), i=1,3)
1 format ("x has been allocated like x(",2(I0,":",I0,","),I0,":",I0,").")
end
这个例子有点不简单,因为它还显示了CFI_deallocate 函数,尽管我们在 C 端有这个额外的级别,但我们仍然可以通过组件 @ 访问该 C 函数中的内存。 987654335@。如果未分配 Fortran 变量,则这是一个空指针;否则它是 Fortran 数组的第一个元素的 C 地址,只要至少有一个元素。
更多细节可以在 TS 文档或即将发布的 Fortran 标准草案中找到。