我正在使用C dll绑定Fortran代码,我希望有一个可与C互操作的Fortran数组。我目前有以下子程序将Fortran数组与C double绑定*:
SUBROUTINE Pack_Inputs( Input , In_X )
TYPE( InputType ) , INTENT(INOUT) :: Input
REAL(KIND=C_DOUBLE) , ALLOCATABLE , TARGET , INTENT(INOUT) :: In_X(:)
IF ( .NOT. ALLOCATED(In_X) ) ALLOCATE( In_X (Input%Xlen) )
DO i = 1,Input%C_obj%Xlen
In_X(i) = Input%X(i)
END DO
Input%C_obj%X = C_LOC(In_X)
END SUBROUTINE Pack_Inputs
然而,我不喜欢当前的代码是我不断分配内存,并且在输入C dll时必须解压缩数组(部分是由于我不愿意使用SAVE
属性在In_X(:)
)。我宁愿在Fortran派生类型中声明In_X
一次。这导致了这篇文章的动机。在此派生类型中:
USE , INSTRINSIC :: ISO_C_BINDING
TYPE , PUBLIC :: InputType
TYPE(InputType_C) :: C_obj
REAL(KIND=C_DOUBLE) , ALLOCATABLE , TARGET :: In_X(:)
REAL , DIMENSION(:) , ALLOCATABLE :: X
REAL , DIMENSION(:) , ALLOCATABLE :: Y
REAL , DIMENSION(:) , ALLOCATABLE :: Z
INTEGER , DIMENSION(:) , ALLOCATABLE :: index
INTEGER :: Xlen
INTEGER :: Ylen
INTEGER :: Zlen
INTEGER :: indexlen
END TYPE InputType
我收到错误:
REAL(KIND=C_DOUBLE) , ALLOCATABLE , TARGET :: In_X(:)
1
Error: Attribute at (1) is not allowed in a TYPE definition
有没有办法消除这个错误?
答案 0 :(得分:1)
之前我遇到过这个问题,而且对我有用的解决方案是将组件声明为POINTER
而不是ALLOCATABLE, TARGET
。我不确定Fortran标准是否不支持它,或者编译器没有实现此功能。我正在使用ifort v12.0.2.137
。
这对您来说是否可以接受?然后,您就可以将其用作指针目标。
TYPE , PUBLIC :: InputType
TYPE(InputType_C) :: C_obj
REAL(KIND=C_DOUBLE),DIMENSION(:),POINTER :: In_X => NULL()
REAL , DIMENSION(:) , ALLOCATABLE :: X
REAL , DIMENSION(:) , ALLOCATABLE :: Y
REAL , DIMENSION(:) , ALLOCATABLE :: Z
INTEGER , DIMENSION(:) , ALLOCATABLE :: index
INTEGER :: Xlen
INTEGER :: Ylen
INTEGER :: Zlen
INTEGER :: indexlen
END TYPE InputType
然后,您可以将In_X
指针与目标数据相关联:
In_X(1:Input%C_obj%Xlen) => Input%X(1:Input%C_obj%Xlen)
请注意,Input%X
也需要具有TARGET
属性。