Строки динамической длины всегда немного хитры с взаимодействием Си. Возможное решение - использовать указатели.
Сначала простой случай, когда вам нужно передать завершенную нулем строку в C-функцию. Если вы действительно передаете строку только в, вы должны убедиться, что завершите ее с помощью c_null_char, таким образом, это направление довольно простое. Вот примеры из 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
И интерфейс поля lua_get выглядит так:
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
И интерфейс C-кода:
void lua_getfield (lua_State *L, int idx, const char *k)
Теперь немного более сложный случай, когда нам приходится иметь дело с возвращаемой строкой из C с динамической длиной. Самое портативное решение, которое я нашел, - это использование указателей.
Вот пример с указателем, где строка дается C-рутиной (также из
Библиотека Aotus, упомянутая выше):
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
где lua_tolstring имеет следующий интерфейс :
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
Наконец, попытка прояснить, как c_ptr может интерпретироваться как строка символов Фортрана:
Предположим, вы получили c_ptr, указывающий на строку:
type(c_ptr) :: a_c_string
И его длина задается переменной len следующего типа:
integer(kind=c_size_t) :: stringlen
Вы хотите получить эту строку в указателе на символьную строку в Фортране:
character,pointer,dimension(:) :: string
Итак, вы делаете отображение:
call c_f_pointer(a_c_string, string, [ stringlen ])