Использование выделяемых целевых переменных в производном типе

Я связываю код Fortran с Cll DLL, и я хотел бы, чтобы массив Fortran был совместим с C. У меня есть следующая подпрограмма для связывания массива 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(:)). Я бы очень хотел заявить 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

Решение

Я сталкивался с этой проблемой раньше, и решение, которое работало для меня, состояло в том, чтобы объявить компонент как 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 атрибут также.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]