Arrays von Strings in Fortran-C-Brücken mit iso_c_binding
-
13-12-2019 - |
Frage
Ich schreibe Code, der eine C-Funktion aus Fortran unter Verwendung des C-Interoperabilitätsmechanismus von Fortran aufruft (eingeführt in Fortran 2003 und implementiert in neueren Versionen von gfortran und ifort).
Diese Antwort ist fast das, was ich brauche, aber ich kann mir nicht ganz vorstellen, welche Schnittstellendeklaration ich in Fortran für eine C-Funktion verwenden soll, die so aussieht:
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;
}
Mir ist nicht klar, wie die Deklaration für die Schnittstelle auf der Fortran-Seite lauten soll:
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
Ich weiß, dass ich mich auch mit dem Problem der Nullterminierung befassen muss.
Lösung
Die Art und Weise, wie wir es tun, besteht darin, a zu verwenden C_PTR
Array, um auf Strings zu zeigen.Zum Beispiel:
CHARACTER(LEN=100), DIMENSION(numStrings), TARGET :: stringArray
TYPE(C_PTR), DIMENSION(numStrings) :: stringPtrs
Dann legen wir unsere Fäden auf stringArray
, denken Sie daran, sie mit Null zu terminieren, wie zum Beispiel:
DO ns = 1, numStrings
stringArray(ns) = "My String"//C_NULL_CHAR
stringPtrs(ns) = C_LOC(stringArray(ns))
END DO
und passieren stringPtrs
zur C-Funktion.
Die C-Funktion hat die Schnittstelle:
void stringFunc(int *numStrings, char **stringArray) {
int i;
for(i=0;i<*numStrings;++i) {
printf("%s\n",stringArray[i]);
}
}