[J3] Getting c_ptr for type(*), dimension(..)

Jeff Hammond jehammond at nvidia.com
Tue Nov 15 10:59:41 UTC 2022


Am I missing something or is it not possible to obtain a Fortran pointer for a type(*), dimension(..) argument without going through C?

I am trying to write a generic interface for a callback, i.e. one that has type(*), dimension(..) arguments.  Inside of my callback, I know what the type and shape are going to be, and therefore can assign them to an appropriate pointer, which I can then operate on appropriately.

This is easily done with a C function that reads the base address from the CFI_cdesc_t, but I cannot figure out how to do it entirely within Fortran.  Did I miss something or is it impossible?

If it is currently impossible to do this without using C, is it unreasonable to ask that we add a feature to make it possible without writing the C conversion function?

Thanks,

Jeff

! #include “ISO_Fortran_binding.h”
! void get_cptr(CFI_cdesc_t * x, void ** y) { *y = x->base_addr; }
module f
    interface
        subroutine get_cptr(x,y) bind(C)
            use, intrinsic :: iso_c_binding, only : c_ptr
            implicit none
            type(*), dimension(..), intent(in) :: x
            type(c_ptr), intent(out) :: y
        end subroutine
    end interface
end module f

module i
    abstract interface
        subroutine M_User_function(i, o, n, d)
            use, intrinsic :: iso_c_binding, only : c_ptr
            implicit none
            type(*), dimension(..), intent(in) :: i
            type(*), dimension(..), intent(inout) :: o
            integer, intent(in) :: n
            type(c_ptr), intent(in) :: d
        end subroutine
    end interface
end module i

module x
    contains
    subroutine X_function(i, o, n, d)
        use, intrinsic :: iso_c_binding, only : c_ptr, c_f_pointer
        use f, only : get_cptr
        implicit none
        type(*), dimension(..), intent(in) :: i
        type(*), dimension(..), intent(inout) :: o
        integer, intent(in) :: n
        type(c_ptr), intent(in) :: d
        type(c_ptr) :: cpi, cpo
        integer, dimension(:), pointer :: fpi, fpo
        ! not allowed to do this:
        ! call c_f_pointer(i,fpi,[size(i)])
        ! call c_f_pointer(o,fpo,[size(o)])
        call get_cptr(i,cpi)
        call get_cptr(o,cpo)
        call c_f_pointer(cpi,fpi,[size(i)])
        call c_f_pointer(cpo,fpo,[size(o)])
    end subroutine
end module x

program main
    use i
    use x
    implicit none
    procedure(M_User_function), pointer :: fp => NULL()
    fp => X_function
end program main


More information about the J3 mailing list