Type(c_ptr) and void *

if type(c_ptr) is equivalent to void * then I should be able to create a specific fortran type that contains my data, declare a member toto of that type as pointer, allocate it then transmit and store in a python class instance as a void * using c_loc(toto) and finally get the fortran member toto of the type using c_f_pointer when python calls fortran.

My final purpose is to suppress all global variables in the Fortran code in order to be able to launch several instance of the code with the python interface.

https://fortran-lang.discourse.group/t/python-class-and-fortran-code/8134

I tested this (full fortran and it works) now I am going to test it with python and python.

module test
  use iso_fortran_env
  implicit none
  
  type struct
    integer(int32)         :: i32
    integer(int64)         :: i64
    real(real32)           :: r32
    real(real64)           :: r64
    integer(int32),pointer :: tab_i32(:)
  contains
    procedure, pass :: display => display
  end type struct
  
contains
  
  subroutine display(ob)
    class(struct) :: ob
    integer       :: i
    
    print '("i32=",i0)',ob%i32
    print '("i64=",i0)',ob%i64
    print '("r32=",f12.5)',ob%r32
    print '("r64=",f12.5)',ob%r64
    print '("size(tab_i32)=",i0)',size(ob%tab_i32)
    do i=1,size(ob%tab_i32)
      print '(t3,"tab(",i2,")=",i2)',i,ob%tab_i32(i)
    enddo
    return
  end subroutine display
  
end module test


program main
  use iso_fortran_env
  use iso_c_binding, only: c_loc,c_ptr,c_f_pointer
  use test
  
  implicit none
  
  type(struct), pointer :: fptr_struct0(:)
  type(struct), pointer :: fptr_struct1(:)
  type(c_ptr)           :: cptr_struct
  integer(int32)        :: i
  
  !> On definit fptr_struct0
  print '(/"On definit fptr_struct0")'
  allocate(fptr_struct0(1))
  
  fptr_struct0(1)%i32=1_int32
  fptr_struct0(1)%i64=2_int64
  fptr_struct0(1)%r32=3.1415_real32
  fptr_struct0(1)%r64=3.1415_real64
  
  allocate(fptr_struct0(1)%tab_i32(1:10))
  do i=1,size(fptr_struct0(1)%tab_i32)
    fptr_struct0(1)%tab_i32(i)=i
  enddo
  
  !> On passe fptr_struct0 en pointeur C
  print '(/"On passe fptr_struct0 en pointeur C")'
  cptr_struct=c_loc(fptr_struct0)
  
  !> On binde fptr_struct0 et fptr_struct1 via cptr_struct
  print '(/"On binde fptr_struct0 et fptr_struct1 via cptr_struct")'
  call c_f_pointer(cptr=cptr_struct, fptr=fptr_struct1, shape=[1])
  
  !> On affiche fptr_struct1
  print '(/"On affiche fptr_struct1")'
  call fptr_struct1(1)%display()
  
  !> On modifie fptr_struct1
  print '(/"On modifie fptr_struct1")'
  deallocate(fptr_struct1(1)%tab_i32)
  allocate(fptr_struct1(1)%tab_i32(1:5))
  do i=1,size(fptr_struct1(1)%tab_i32)
    fptr_struct1(1)%tab_i32(i)=10*i
  enddo
  
  !> On affiche fptr_struct0
  print '(/"On affiche fptr_struct0")'
  call fptr_struct0(1)%display()
  
  !> On désalloue fptr_struct0
  deallocate(fptr_struct0)
  fptr_struct0=>null()
  fptr_struct1=>null()
end program main