Dynamic-length strings are always a little complicated with C interaction. A possible solution is to use pointers.
First, a simple case where you need to pass a string with a null character to a C function. If you really only pass the string inside, you must ensure that it terminates with c_null_char, so this direction is pretty straight forward. Here are examples from the LuaFortran Interface :
subroutine flu_getfield(L, index, k) type(flu_State) :: L integer :: index character(len=*) :: k integer(kind=c_int) :: c_index character(len=len_trim(k)+1) :: c_k c_k = trim(k) // c_null_char c_index = index call lua_getfield(L%state, c_index, c_k) end subroutine flu_getfield
And the lua_getfield interface looks like this:
subroutine lua_getfield(L, index, k) bind(c, name="lua_getfield") use, intrinsic :: iso_c_binding type(c_ptr), value :: L integer(kind=c_int), value :: index character(kind=c_char), dimension(*) :: k end subroutine lua_getfield
And the C code interface:
void lua_getfield (lua_State *L, int idx, const char *k)
Now a slightly more complicated case when we have to deal with a returned string from C with dynamic length. The most portable solution I've found so far is using pointers. Here is an example with a pointer where the line is given by C-Routine (also from Aotus, mentioned above):
function flu_tolstring(L, index, len) result(string) type(flu_State) :: L integer :: index integer :: len character,pointer,dimension(:) :: string integer :: string_shape(1) integer(kind=c_int) :: c_index integer(kind=c_size_t) :: c_len type(c_ptr) :: c_string c_index = index c_string = lua_tolstring(L%state, c_index, c_len) len = int(c_len,kind=kind(len)) string_shape(1) = len call c_f_pointer(c_string, string, string_shape) end function flu_tolstring
where lua_tolstring has the following interface :
function lua_tolstring(L, index, len) bind(c, name="lua_tolstring") use, intrinsic :: iso_c_binding type(c_ptr), value :: L integer(kind=c_int), value :: index integer(kind=c_size_t) :: len type(c_ptr) :: lua_tolstring end function lua_tolstring
Finally, here's an attempt to figure out how c_ptr can be interpreted as a Fortran character string: Suppose you get c_ptr pointing to a string:
type(c_ptr) :: a_c_string
And its length is set by the variable len with the following type:
integer(kind=c_size_t) :: stringlen
You want to get this string in a pointer to a character string in Fortran:
character,pointer,dimension(:) :: string
So you are doing the mapping:
call c_f_pointer(a_c_string, string, [ stringlen ])