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