Массивы строк в мостах Fortran-C с использованием iso_c_binding - PullRequest
12 голосов
/ 13 марта 2012

Я пишу код, который будет вызывать функцию C из Fortran с использованием механизма взаимодействия Fortran C (введен в 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;
}

Я не совсем понимаю, чтообъявление должно быть для интерфейса на конце Фортрана:

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

Я знаю, что мне придется иметь дело и с проблемой нулевого завершения.

1 Ответ

10 голосов
/ 13 марта 2012

То, как мы это делаем, - использование массива 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]);
    }
 }
...