Using allocatable, target variables in derived types with ISO_C_BINDING

Using allocatable, target variables in derived types with ISO_C_BINDING

I'm binding Fortran code with a C dll, and I would like to have a Fortran array inter-operable with C. I currently have the following subroutine to bind the Fortran array with a 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

However, what I don't like about the current state of code is that I am constantly allocating memory, and having to unpack the array when the C dll is entered (partly driven by my reluctance to use the `SAVE` attribute on `In_X(:)`). I would rather much declare `In_X` once, inside a Fortran derived type. This leads to the motivation for this post. In this derived type:

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

But this leads to the error:

error #6516: This attribute specification is not valid for a component definition statement.   [TARGET]

because of TARGET.  Is there a pathway to get around this issue?

2 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

TARGET is an attribute for variables, not for components of a derived type.

I am not completely sure what you are doing here. Where is Pack_Inputs called from?  ALLOCATABLE arrays are not interoperable with C. (Neither are POINTER arrays.)  You could use TYPE(C_PTR) as a component - it might then make sense to use a POINTER array to allocate the storage, and then use C_LOC to get the address to store into the C_PTR. Coming in to Fortran you can use C_F_POINTER to map that to a Fortran POINTER. I am not sure this is relevant to what you're doing - can you explain in more detail? Maybe provide some C code as context?

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today