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

C++ 在派生类型中使用可分配的目标变量,c++,c,fortran,fortran-iso-c-binding,language-interoperability,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) ::

我正在用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时必须解包数组(部分原因是我不愿意在X(:)中使用
上的
SAVE
属性)。我宁愿在Fortran派生类型中声明一次
。这导致了这个职位的动机。在此派生类型中:

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

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

我以前遇到过这个问题,我的解决方案是将组件声明为
指针
,而不是
可分配的目标
。我不确定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
然后,您可以将\u X中的
指针与目标数据关联:

In_X(1:Input%C_obj%Xlen) => Input%X(1:Input%C_obj%Xlen)

请注意,
Input%X
也需要有一个
TARGET
属性。

可能,但可能我没有正确应用它。我得到错误:
IF(.NOT.ALLOCATED(In_X))ALLOCATE(In_X(Input%Xlen))error:'ALLOCATED'内在的(1)处的'array'参数必须是可分配的
谢谢!您的回答提供了灵感,尽管我采取了稍微不同的方法,因为我使用
C\u F\u指针(…)
,因为我在初始化时用C声明大小和数组内容。您关于
REAL(KIND=C\u DOUBLE)、DIMENSION(:),POINTER::In\u X=>NULL()
的注释确实帮助我走上了正确的道路。该标准不支持它。整个类型的实例必须声明为目标。