2012-03-13 14 views
11

Scrivo codice che chiamerà una funzione C di Fortran utilizzando il meccanismo di interoperabilità C di Fortran (introdotto in Fortran 2003 e implementato nelle versioni più recenti di gfortran e ifort).Array di stringhe nei bridge Fortran-C che utilizzano iso_c_binding

This answer è quasi quello che mi serve, ma non riesco a ottenere la mia testa intorno a che cosa dichiarazione di interfaccia dovrei usare in Fortran per una funzione C che assomiglia a questo:

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; 
} 

Io non sono chiare ciò che la dichiarazione dovrebbe essere per l'interfaccia alla fine 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 

so che dovrò affrontare la questione terminazione null troppo.

+0

Molte grazie per francescalus utente per la modifica utilmente a questa domanda per farmi sembrare meno educato rimuovendo un "grazie" alla fine di esso. Grazie al cielo, gli utenti come loro sono in giro per impedire alle persone di fare domande illeggibili con la cortesia di tutti i giorni. – JoeZuntz

risposta

8

Il modo in cui lo facciamo è utilizzare un array C_PTR in modo che punti alle stringhe. Ad esempio:

CHARACTER(LEN=100), DIMENSION(numStrings), TARGET :: stringArray 
TYPE(C_PTR), DIMENSION(numStrings) :: stringPtrs 

poi fissato nostre corde in stringArray, ricordando null-terminate le quali:

DO ns = 1, numStrings 
    stringArray(ns) = "My String"//C_NULL_CHAR 
    stringPtrs(ns) = C_LOC(stringArray(ns)) 
END DO 

e passare stringPtrs alla funzione C.

La funzione C ha l'interfaccia:

void stringFunc(int *numStrings, char **stringArray) { 
    int i; 
    for(i=0;i<*numStrings;++i) { 
     printf("%s\n",stringArray[i]); 
    } 
} 
+0

Meraviglioso, grazie mille per la risposta eccezionalmente rapida e utile! Per completezza, il tipo nell'interfaccia è quindi "tipo (c_ptr), dimensione (numStrings)" – JoeZuntz

+0

corretto, nel nostro codice non forniamo effettivamente un'interfaccia per la funzione C, la trattiamo come "esterna", quindi io non ha un semplice esempio del blocco di interfaccia a portata di mano. – tpg2114

+1

Questo non è il Fortran 2003 standard (vedere la sezione 15.2.1) o il 2008 (sezione 15.3.2): ** Se il tipo è carattere, il parametro del tipo di lunghezza è interoperabile se e solo se il suo valore è uno. **. E gfortran segnala questo (usando * character (len = ...) * con C_LOC) come errore. C'è anche una [discussione] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36759) su questo problema in GCC bugzilla. –