I was experimenting with an interface to a C library and realised that I would need to deal with pointers to C strings and if possible in a way that is transparent on the Fortran side. So: turn the type(c_ptr) into a string that behaves as if it is an ordinary Fortran string (because otherwise dealing with them is awkward). There are a number of possibilities for that, one being creating a copy of the contents in an ordinary Fortran variable. But what if I want to avoid the copy?
Well, here is the C code as an example, the function returns a pointer to a string ending in a NUL character:
/* getstring.c --
Trivial function to return a static string
*/
#include <string.h>
void getstring_c( char **string, int *length ) {
*string = "Hello" ;
*length = strlen(*string) ;
}
(quite trivial, but the interface is typical for what I was dealing with)
The Fortran program below calls this function and turns the pointer into a Fortran pointer that behaves as a string of the right length:
program string_pointer
implicit none
character(len=:), pointer :: p_string
call getstring( p_string)
write(*,*) '>', p_string, '<'
write(*,*) len(p_string)
contains
subroutine getstring( p_string )
use iso_c_binding
character(len=:), pointer :: p_string
interface
subroutine getstring_c( c_string, length ) bind(C)
import :: c_ptr
type(c_ptr), intent(out) :: c_string
integer, intent(out) :: length
end subroutine getstring_c
end interface
type(c_ptr) :: c_string
integer :: length
call getstring_c( c_string, length )
call c_f_pointer( c_string, p_string )
p_string => p_string(1:length) ! Would that work? Yes :)
end subroutine getstring
end program string_pointer
I was pleased to see it works. No copy required, no array of individual characters, simply a string. I only hope it is standard-conforming. What are other possibilities to achieve this?
The goal I have in mind: provide an interface to such a C library with a minimal amount of C code.