重载的fortran接口具有不同的排名

Spi*_*ros 4 fortran overloading rank

在Fortran模块中,我有一个函数,它接受一个数组及其名称,从数据库(实际调用C函数)获取数组的形状,将数组复制到临时缓冲区并将缓冲区传递给另一个处理的C函数它.此Fortran函数的整数数据名称为fs_WriteData_i,实数为fs_WriteData_f,双精度为f​​s_WriteData_d.所有这些功能不仅接受一维阵列,还接受2D,3D和4D阵列,并且它们完美地工作.以下是其中一个子程序的接口:

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
Run Code Online (Sandbox Code Playgroud)

如果用户fs_WriteData_d('name', data)使用双精度数据调用,最多为4维数组,则此子例程执行该作业.

现在,问题是:我想提供一个名为fs_WriteData的通用重载接口,所以我使用了

interface fs_WriteData
    module procedure fs_WriteData_i, &
                     fs_WriteData_f, &
                     fs_WriteData_d
end interface fs_WriteData
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用:编译器声明如果用户只是调用它就找不到正确的实现fs_WriteData('name', data),这是因为与所有这些函数的排名不匹配.

是否有一种聪明的方法可以避免使用相同的内容编写所有fs_WriteData_d_1d,fs_WriteData_d_2d,...子例程,以使模块更易于维护?

提前谢谢了.

Ian*_*anH 6

有点.

正如您所发现的那样,除了F2008之外,选择通用调用的特定过程的规则除了其他内容和元素过程之外还需要类型,种类和等级的匹配(所谓的TKR兼容).即使数据伪参数是假定大小(因此在直接调用特定过程时它可以与任何非零等级的实际参数相关联),它仍然被认为是TKR兼容性目的的一级参数.

最近发布的关于Fortran与C的进一步互操作性的技术规范(TS29113)增加了假设等级的概念.取决于你在可执行部分内所做的事情fs_WriteData_d(传递给C几乎就是你能做的所有事情)可能适合 - 类型/种类/等级匹配的规则已被扩展,使得假定的等级实际或伪参数是兼容的等级.相当重要的问题是编译器支持 - 我认为目前没有任何编译器支持这个TS!

对于F201X之前的语言标准编码,有几种可能性:

  • 为每个要支持的排名编写一系列瘦包装器子程序,然后使用这些包装器子程序调用1D表单的特定过程,依靠序列关联将多维数组映射到1D数组.

  • 将子例程的主体放在单独的文件中,并将该文件包含在骨架接口内,以用于每个等级的子例程.这种方法要求子程序体内的代码在词法上是等级独立的.在某些情况下,代码也可以以独立于类型的方式编写,并且您可以为要支持的各种类型使用公共包含文件.虽然这消除了与"复制和粘贴"代码的更改管理相关的问题,但处理INCLUDE文件可能会有点痛苦.

两者的某些组合也可能是合适的.

(可能存在第三种选择,使用C互操作性为每个排名和类型组合设置的接口主体的绑定名称设置为一个实现过程的绑定名称,但我不确定是否(ab)使用C互操作性是合法的.)

如果您正在寻找不同类型变体的常见命名,那么另一种可能性(再次,取决于您在正文中所做的事情)是将数据参数作为来自ISO_C_BINDING内在模块的C_PTR,并推动获取的要求C_LOC将实际参数反馈回子程序的客户端代码.