Print

Print


Thanks Jim and Van for your replies.

The approach you give below does indeed work, but strlen doesn't have
the characteristics to used in a specification expression, so the length
value needs to be passed in instead -- no big deal.

Also the same kind of idea can be used for a Fortran 'strlen' to avoid the
need to specify an array length in the c_f_pointer expression that Jim
suggested;  initialize a scalar character pointer instead and pass it to
an assumed-size character(1) dummy array instead.

Cheers,
  Neil

PS: It looks like I have some free time to play with this stuff today
(http://www.cnn.com/2011/US/06/27/new.mexico.los.alamos/index.html?hpt=hp_t2
);
one of the (few) times I'm glad I don't live up on the hill.

On Fri, Jun 24, 2011 at 4:36 PM, Van Snyder <[log in to unmask]> wrote:

> **
> Maybe the problem of setting the length parameter can be finessed:
>
>   type(c_ptr) :: A
>   character(:), pointer :: B
>   a = some_C_function ()
>   b => FunnyFunction ( a )
>
>   contains
>
>   function FunnyFunction ( A )
>     type(c_ptr), intent(in) :: A
>     character(strlen(a)), pointer :: FunnyFunction
>     call c_f_pointer ( a, funnyFunction )
>   end function FunnyFunction
>
>
> Van Snyder wrote:
>
> Neil's problem reveals a deficiency in C_F_POINTER: although the shape of
> the pointer can be set, the deferred length parameters cannot.
>
> If a pointer array is contiguous, why not allow a pointer to the array to
> be a scalar with a length equal to the size of the array, or indeed a
> pointer with any rank, and the product of the length and extents equal to
> the size of the array?
>
> If C_F_POINTER were defined as
>
>   C_F_POINTER ( CPTR, FPTR, [SHAPE, PARAMETERS] )
>
> where PARAMETERS is an integer array whose elements give values of FPTR's
> deferred length parameters, Neil's problem would be simple:
>
>   type(c_ptr) :: A
>   character(:), pointer :: B
>   a = some_C_function ()
>   call c_f_pointer ( a, b, parameters=[strlen(a)] )
>   print '("character(",i0,") = ''",a,"''")', len(b), b
>
> Neil Carlson wrote:
>
> I occasionally need to interoperate with C functions that return a pointer
> to a null-delimited string which I need to convert to a usable Fortran
> character value.  With F2003 this is much easier than it used to be.
> I have a solution that works, but I'm wondering if I've made it more
> complicated than it needs to be.  Briefly, the length of the string
> must be computed and the C pointer converted to a pointer to a
> character(len=1) array, and then the contents of the array copied to
> a scalar character value with the right len value.
>
> If the C function prototype is
>
>     const char* some_C_function();
>
> I've got:
>
>    interface
>       function some_C_function() result(string) bind(c)
>         use iso_c_binding
>         type(c_ptr) :: string
>       end function
>     end interface
>
>     character(len=:,kind=c_char), allocatable :: string
>     call c_f_string(some_C_function(), string)
>
> With:
>
>   subroutine c_f_string (cptr, string)
>     use iso_c_binding
>     type(c_ptr), intent(in) :: cptr
>     character(kind=c_char,len=:), allocatable :: string
>     character(kind=c_char), pointer :: fptr(:) => null()
>     integer :: n
>     interface ! to the libc function strlen
>       function strlen(s) result(len) bind(c)
>         use iso_c_binding
>         type(c_ptr), value :: s
>         integer(c_size_t) :: len
>       end function
>     end interface
>     call c_f_pointer (cptr, fptr, shape=[strlen(cptr)])
>     allocate(character(len=size(fptr),kind=c_char) :: string)
>     do n = 1, size(fptr)
>       string(n:n) = fptr(n)
>     end do
>   end subroutine c_f_string
>
> Two things bother me about this.  First is using the libc function
> strlen to compute the length of the string.  I'm not sure how to do
> this from the Fortran side, but wish I could.  Second is whether
> it is possible to eliminate the copy; ideally I just want to dress
> the contiguous sequence of chars that C points to as a Fortran
> character value.
>
> Thoughts?
>
>  Neil
>
>
>
>