可以使用数组参数从Fortran调用标量C函数吗?

sig*_*gma 4 c interop fortran fortran2003 fortran-iso-c-binding

我最近遇到过一种情况,我想从Fortran调用一个C函数,因为它有一段很有用的C代码.为了方便数组操作,我希望能够使用数组参数调用此函数,但它只接受标量参数.

在Fortran中,当然可以简单地声明一个elemental实现此目的的过程,并且可以声明一个C过程的接口bind(C).但是,由于C没有元素过程的概念,Fortran(2008)标准排除了这种组合:

C1246元素过程不应具有BIND属性.

那么,这个功能可以在Fortran中实现吗?

sig*_*gma 7

经过一些搜索,我发现使用Fortran 2003和iso_c_binding内部模块,这既可行又简单明了; 我想我应该在这里记录下来.具有该bind属性的接口仍然可以pure,因此可以在Fortran过程中引用它本身elemental.

以下是C99宏的简短示例,isnan如果其参数为NaN,则返回非零整数值.当然,这也可以用于任何没有副作用的用户定义的C/C++函数.

elemental function isnan(val)
  use, intrinsic :: iso_c_binding
  implicit none

  real(c_double), intent(in) :: val
  logical(c_bool) :: isnan

  interface
    pure function isnan_C(val) bind(C, name = 'isnan')
      import
      ! Pass the parameter by value:
      real(c_double), value, intent(in) :: val
      integer(c_int) :: isnan_C
    end function
  end interface

  isnan = isnan_C(val) /= 0_c_int
end function
Run Code Online (Sandbox Code Playgroud)

使用具有一些NaN值的数组的示例输出:

program main
  use, intrinsic :: iso_c_binding
  implicit none

  real(c_double) :: nan(2,2) = 0.
  nan(:,2) = nan(1,1)/0.

  write(*,'(4F6.2 / 4L6)') nan, isnan(nan) ! Output: 0.00 0.00  NaN  NaN
                                           !            F    F    T    T
end program
Run Code Online (Sandbox Code Playgroud)