在派生类型中使用可分配的目标变量

时间:2013-06-14 18:14:34

标签: c++ c fortran fortran-iso-c-binding language-interoperability

我正在使用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

有没有办法消除这个错误?

1 个答案:

答案 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属性。