基本上有两种方法可以将数组传递给Fortran 90/95中的子程序:
PROGRAM ARRAY
INTEGER, ALLOCATABLE :: A(:,:)
INTEGER :: N
ALLOCATE(A(N,N))
CALL ARRAY_EXPLICIT(A,N)
! or
CALL ARRAY_ASSUMED(A)
END PROGRAM ARRAY
SUBROUTINE ARRAY_EXPLICIT(A,N)
INTEGER :: N
INTEGER :: A(N,N)
! bla bla
END SUBROUTINE ARRAY_EXPLICIT
SUBROUTINE ARRAY_ASSUMED(A)
INTEGER, ALLOCATABLE :: A(:,:)
N=SIZE(A,1)
! bla bla
END SUBROUTINE ARRAY_ASSUMED
Run Code Online (Sandbox Code Playgroud)
您需要第二个显式接口,通常是通过使用模块.
从FORTRAN77开始,我习惯了第一种选择,如果你传递整个数组,我认为这也是最有效的.
显式形状的好处是我也可以调用子例程并将数组视为向量而不是矩阵:
SUBROUTINE ARRAY_EXPLICIT(A,N)
INTEGER :: N
INTEGER :: A(N**2)
! bla bla
END SUBROUTINE ARRAY_EXPLICIT
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种很好的方法来使用第二个假定的形状界面来做这种事情而不复制它.
最近,我在 Stack Overflow 上阅读了一篇关于寻找完美平方的整数的文章。由于我想玩这个,我写了以下小程序:
PROGRAM PERFECT_SQUARE
IMPLICIT NONE
INTEGER*8 :: N, M, NTOT
LOGICAL :: IS_SQUARE
N=Z'D0B03602181'
WRITE(*,*) IS_SQUARE(N)
NTOT=0
DO N=1,1000000000
IF (IS_SQUARE(N)) THEN
NTOT=NTOT+1
END IF
END DO
WRITE(*,*) NTOT ! should find 31622 squares
END PROGRAM
LOGICAL FUNCTION IS_SQUARE(N)
IMPLICIT NONE
INTEGER*8 :: N, M
! check if negative
IF (N.LT.0) THEN
IS_SQUARE=.FALSE.
RETURN
END IF
! check if ending 4 bits belong to (0,1,4,9)
M=IAND(N,15)
IF (.NOT.(M.EQ.0 .OR. M.EQ.1 .OR. M.EQ.4 .OR. M.EQ.9)) THEN …Run Code Online (Sandbox Code Playgroud) 根据Fortran标准信息,我可以找到(F77,F90/95)一个数组声明符,其中没有下限假定该下限为1.由于上限需要大于或等于下限,会不允许以下声明:
INTEGER A(0)
Run Code Online (Sandbox Code Playgroud)
但是,我不能让ifort和gfortran以任何方式抱怨这个说法.编译器是否需要将此标记为错误?
我习惯使用以下语法
subroutine CalcA(A,N)
!DEC$ ATTRIBUTES DLLEXPORT :: CALCA
!DEC$ ATTRIBUTES ALIAS:'CalcA' :: CalcA
IMPLICIT NONE
...
end subroutine CalcA
Run Code Online (Sandbox Code Playgroud)
它在.dll中生成导出的函数

所以现在我ISO_C_BINDING用以下代码尝试新的
subroutine CalcA(A,N) BIND(C, NAME="CalcA")
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
...
end subroutine CalcA
Run Code Online (Sandbox Code Playgroud)
但是没有创建导出功能

那我在这里错过了什么?新的如何iso_c_binding取代已弃用的!DEC$ ATTRIBUTE DLLEXPORT声明?
PS.我通过VS2010在Win7-64平台上使用英特尔Fortran XE 2013.