type :: C_RecordInfo_t
type(c_ptr) :: data
integer(c_int64_t) :: dimensions(15)
end type C_RecordInfo_t
and DATA is a pointer:
real(8), pointer :: DATA(:,:)
or
integer, pointer :: DATA(:,:,:)
Unfortunately, when someone will try to hide c_f_pointer call, in general case he must declare all necessary types and shapes of arrays. To prove this:
subroutine test(recordinfo, fptr)
type(recordinfo_t) :: recordinfo
class(*), pointer :: fptr(..)
call c_f_pointer(recordinfo%data, fptr_i4, recordinfo%dimensions(1:size(shape(fptr_i4))))
end subroutine test
leads to
43 | call c_f_pointer(recordinfo%data, fptr, recordinfo%dimensions(1:size(shape(fptr))))
Error: Assumed-rank argument at (1) is only permitted as actual argument to intrinsic inquiry functions
43 | call c_f_pointer(recordinfo%data, fptr, recordinfo%dimensions(1:size(shape(fptr))))
Error: FPTR argument at (1) to C_F_POINTER shall not be polymorphic
Then, removing polymorphic type:
type(*), pointer :: fptr(:)
one can obtain the following error:
40 | subroutine test(recordinfo, fptr)
Error: Assumed-type variable fptr at (1) may not have the ALLOCATABLE, CODIMENSION, POINTER or VALUE attribute
43 | call c_f_pointer(recordinfo%data, fptr, recordinfo%dimensions(1:size(shape(fptr))))
Error: Assumed-type argument at (1) is not permitted as actual argument to the intrinsic c_f_pointer
I suggest adding type(F_ptr) to manage these things in a simpler way. The idea of this type is easily casting it into other Fortran pointers.
In the last case, rank can be modified (like rerank( type(f_ptr) :: pointer, integer :: shape(:)) ). c_f_pointer routine also can set the shape of this array.
Then, this type(F_ptr) can be assigned to another Fortran pointer. For example:
type(F_ptr) :: A_ptr(..)
integer, pointer :: Ai_1D(:), Ai_2D(:,:)
real, pointer :: Ar_1D(:), Ar_2D(:,:)
call c_f_pointer(some_C_ptr, A_ptr, shape=[8]) ! so, A_ptr has rank 1
Ai_1D = A_ptr ! ok, size(Ai_1D) == 8
Ai_2D = A_ptr ! runtime error, ranks are not the same
Ar_1D = A_ptr ! ok, size(Ar_1D) == 8
Ar_2D = A_ptr ! runtime error, ranks are not the same
! rerank, length can not be the same
call rerank(A_ptr, shape=[2,3]) ! now, A_ptr has rank 2
Ai_1D = A_ptr ! runtime error, ranks are not the same
Ai_2D = A_ptr ! ok, shape(Ai_2D) == (/ 2, 3 /)
Ar_1D = A_ptr ! runtime error, ranks are not the same
Ar_2D = A_ptr ! ok, shape(Ar_2D) == (/ 2, 3 /)
Then, for my case, it can be used as follows:
function get_data_ptr(recordinfo, ndim) result(fptr)
type(recordinfo_t) :: recordinfo
type(F_ptr) :: fptr(..)
call c_f_pointer(recordinfo%data, fptr, recordinfo%dimensions(1:ndim))
end function
Dear all,
I tried to load data from
type(C_ptr)
into Fortran pointer arrays.One can guess that it can be easily done by
where
recordinfo
type is defined as follows:and
DATA
is a pointer:or
Unfortunately, when someone will try to hide
c_f_pointer
call, in general case he must declare all necessary types and shapes of arrays. To prove this:leads to
Then, let's try assumed-size array:
And it gives the following error:
Then, removing polymorphic type:
one can obtain the following error:
I suggest adding
type(F_ptr)
to manage these things in a simpler way. The idea of this type is easily casting it into other Fortran pointers.It can be defined as follows:
In the last case, rank can be modified (like
rerank( type(f_ptr) :: pointer, integer :: shape(:))
).c_f_pointer
routine also can set the shape of this array. Then, thistype(F_ptr)
can be assigned to another Fortran pointer. For example:Then, for my case, it can be used as follows:
and, later: