在 Fortran 模块中,我有一个函数,它接受一个数组及其名称,从数据库(实际上调用一个 C 函数)获取数组的形状,将数组复制到临时缓冲区中并将缓冲区传递给另一个 C 函数来处理它。此 Fortran 函数的名称为 fs_WriteData_i(用于整数数据)、fs_WriteData_f(用于实数)和 fs_WriteData_d(用于 double )。所有这些函数不仅接受一维数组,还接受 2D、3D 和 4D 数组,并且它们工作得很好。下面是这些子例程之一的接口(interface):
subroutine fs_WriteData_d(fieldname, data)
use, intrinsic :: iso_c_binding
implicit none
real(c_double), dimension(*) :: data
character :: fieldname*(*)
! ...
end subroutine fs_WriteData_d
如果用户调用
fs_WriteData_d('name', data)
数据是 double 的,最多 4 维数组,这个子程序可以完成这项工作。现在,问题是:我想提供一个名为 fs_WriteData 的通用重载接口(interface),所以我使用
interface fs_WriteData
module procedure fs_WriteData_i, &
fs_WriteData_f, &
fs_WriteData_d
end interface fs_WriteData
不幸的是,这不起作用:编译器指出如果用户只是调用
fs_WriteData('name', data)
,它将找不到正确的实现。 ,这是因为与所有这些函数的排名不匹配。是否有一种巧妙的方法可以避免编写所有 fs_WriteData_d_1d、fs_WriteData_d_2d、... 子程序的内容相同,从而使模块更易于维护?
提前谢谢了。
最佳答案
有点。
正如您所发现的,从 F2008 开始,为通用调用选择特定过程的规则除其他事项和基本过程外,还需要类型、种类和等级的匹配(所谓的 TKR 兼容)。即使假设数据虚拟参数的大小(因此在直接调用特定过程时,它可以与任何非零等级的实际参数相关联),出于 TKR 兼容性的目的,它仍然被视为等级一的参数。
最近发布的关于 Fortran 与 C 的进一步互操作性的技术规范 (TS29113) 增加了假定等级的概念。取决于您在 fs_WriteData_d
的可执行部分中所做的事情(传递给 C 几乎是你能做的所有事情)可能适合 - 类型/种类/等级匹配的规则已经扩展,使得假定等级实际或虚拟参数是兼容的,无论等级如何。相当重要的问题是编译器支持——我认为目前没有任何编译器支持这个 TS!
对于 F201X 之前的语言标准编码,有几种可能性:
两者的某种组合也可能是合适的。
(可能存在第三种选择,使用 C 互操作性将为每个等级和类型组合编写的接口(interface)主体的绑定(bind)名称设置为一个实现过程的绑定(bind)名称,但我不确定 C 的(ab)用法是否互操作性是合法的。)
如果您所追求的只是不同类型变体的通用命名,那么另一种可能性(再次取决于您在正文中执行的操作)是将数据参数作为 ISO_C_BINDING 内部模块中的 C_PTR 并插入采取的要求将实际参数的 C_LOC 返回到子例程的客户端代码中。
关于fortran - 不同等级的重载fortran接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14434293/