Массивы строк в мостах Fortran-C с использованием iso_c_binding
-
13-12-2019 - |
Вопрос
Я пишу код, который будет вызывать функцию C из Fortran, используя механизм взаимодействия C Fortran (введенный в Fortran 2003 и реализованный в более новых версиях gfortran и ifort).
Этот ответ это почти то, что мне нужно, но я никак не могу взять в толк, какое объявление интерфейса я должен использовать в Fortran для функции C, которая выглядит следующим образом:
int use_array(int n, char * array[]){
int i;
for(i=0; i<n; i++){
printf("Item %d = %s\n",i,array[i]);
}
return n;
}
Мне не ясно, каким должно быть объявление для интерфейса на стороне Fortran:
interface
function use_array(n, x) bind(C)
use iso_c_binding
integer (c_int) use_array
integer (c_int), value :: n
character(c_char) WHAT_SHOULD_GO_HERE? :: x
end function use_array
end interface
Я знаю, что мне тоже придется иметь дело с проблемой нулевого завершения.
Решение
Способ, которым мы это делаем, заключается в использовании C_PTR
массив, указывающий на строки.Например:
CHARACTER(LEN=100), DIMENSION(numStrings), TARGET :: stringArray
TYPE(C_PTR), DIMENSION(numStrings) :: stringPtrs
затем мы устанавливаем наши струны в stringArray
, не забывая обнулять их, например:
DO ns = 1, numStrings
stringArray(ns) = "My String"//C_NULL_CHAR
stringPtrs(ns) = C_LOC(stringArray(ns))
END DO
и пройти stringPtrs
к функции C.
Функция C имеет интерфейс:
void stringFunc(int *numStrings, char **stringArray) {
int i;
for(i=0;i<*numStrings;++i) {
printf("%s\n",stringArray[i]);
}
}