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

Vipul Parekh parekhvs at gmail.com
Wed Nov 16 03:34:28 UTC 2022


On Tue, Nov 15, 2022 at 6:00 AM Jeff Hammond via J3 <
j3 at mailman.j3-fortran.org> wrote:

> 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?
>

Hi Jeff,

Apologies if I am misunderstanding your inquiry.

You will know the Fortran standard has under the TYPE specifier section,
"C715 An assumed-type variable name shall not appear in a designator or
expression except as an actual argument corresponding to a dummy argument
that is assumed-type, or as the first argument to the intrinsic function
IS_CONTIGUOUS, LBOUND, PRESENT, RANK, SHAPE, SIZE, or UBOUND, or the
function C_LOC from the intrinsic module ISO_C_BINDING."

Given above, have you tried employing the C_LOC function along with the
TARGET attribute on your assumed-type (TYPE(*)) argument?  If yes, did that
not work, or is that not what you're after?

Based on the description in your email, here is a small reproducer of a
program I envisioned and it works as I expect: perhaps you will take a look
at it and see if that you're after, or let me know if I misunderstood your
question altogether:  In the example below, you will note the code makes
use of what you write, " 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."  So you can see the
"px" pointer in the Fcallback procedure gets you the object you describe.

! Fortran program in p.f90 file
module m
   use, intrinsic :: iso_c_binding, only : c_int, c_loc, c_f_pointer
   interface
      subroutine Csub( a ) bind(C, name="Csub")
         import :: c_int
         ! Argument list
         integer(c_int), intent(inout) :: a(:,:)
      end subroutine
   end interface
   integer(c_int) :: x(2,3)
contains
   subroutine Fcallback( a ) bind(C, name="Fcallback")
      ! Argument list
      type(*), intent(inout), target :: a(..)
      integer(c_int), pointer :: px(:,:)
      print *, "In Fortran callback:"
      call c_f_pointer( cptr=c_loc(a), fptr=px, shape=shape(x) )
      print *, "x = ", px
   end subroutine
end module
   use m
   call Csub( x )
end

// C "library" function; it doesn't have it to be in C; in c.c file
#include <stdio.h>
#include "ISO_Fortran_binding.h"

extern void Fcallback(CFI_cdesc_t *);

void Csub(CFI_cdesc_t * d) {

   // Presume Fortran descriptor is for rank-2 object
   CFI_index_t extents[2];
   int i, j, n;
   int *x;

   x = (int *)d->base_addr;
   extents[0] = d->dim[0].extent;
   extents[1] = d->dim[1].extent;

   n = 0;
   for (i = 0; i < extents[1]; i++)
   {
      for (j = 0; j < extents[0]; j++)
      {
         n++;
         *(x + n - 1) = n;
      }
   }
   Fcallback(d);
   return;
}

Running the above on Windows OS with Intel Fortran oneAPI compiler and
Microsoft C/C++ companion processor, I get the following:
C:\temp>ifort /c /standard-semantics p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on
Intel(R) 64, Version 2021.7.0 Build 20220726_000000
Copyright (C) 1985-2022 Intel Corporation.  All rights reserved.


C:\temp>cl /c /W3 /EHsc c.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.33.31630 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

c.c

C:\temp>link p.obj c.obj /subsystem:console /out:p.exe
Microsoft (R) Incremental Linker Version 14.33.31630.0
Copyright (C) Microsoft Corporation.  All rights reserved.


C:\temp>p.exe
 In Fortran callback:
 x =  1 2 3 4 5 6

Hope this is of some help to you.

Regards.
Vipul Parekh
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20221115/14fb36a0/attachment-0003.htm>


More information about the J3 mailing list