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