2012-03-13 2 views
11

J'écris du code qui appellera une fonction C de Fortran en utilisant le mécanisme d'interopérabilité C de Fortran (introduit dans Fortran 2003 et implémenté dans les nouvelles versions de gfortran et ifort).Tableaux de chaînes dans les ponts Fortran-C utilisant iso_c_binding

This answer est presque ce que je dois, mais je ne peux pas tout à fait obtenir ma tête autour de ce que la déclaration que je devrais utiliser l'interface en Fortran pour une fonction C qui ressemble à ceci:

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

Je ne suis pas clair ce que la déclaration devrait être de l'interface à l'extrémité 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 

Je ne sais que je vais devoir faire face à la question null-termination aussi.

+0

Un grand merci pour francescalus utilisateur pour éditer utilement cette question pour me faire paraître moins polie en enlevant un « merci » à la fin de celui-ci. Dieu merci, les utilisateurs comme eux sont là pour empêcher les gens de rendre les questions illisibles avec la courtoisie de tous les jours. – JoeZuntz

Répondre

8

La façon dont nous le faisons est d'utiliser un tableau C_PTR pour pointer vers des chaînes. Par exemple:

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

nous fixons nos chaînes en stringArray, se souvenant de leur null-fin comme:

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

et passer stringPtrs à la fonction C.

La fonction C a l'interface:

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

Merveilleux, merci beaucoup pour la réponse exceptionnellement rapide et utile! Par souci de complétude, le type dans l'interface est alors "type (c_ptr), dimension (numStrings)" – JoeZuntz

+0

Correct, dans notre code nous ne fournissons pas d'interface pour la fonction C, nous la traitons comme "external" donc je n'a pas eu un exemple facile du bloc d'interface en main. – tpg2114

+1

Ceci n'est pas standard Fortran 2003 (voir section 15.2.1) ou 2008 (section 15.3.2): ** Si le type est character, le paramètre type de longueur est interopérable si et seulement si sa valeur est un. **. Et gfortran signale ceci (en utilisant le caractère * (len = ...) * avec C_LOC) comme une erreur. Il y a aussi une [discussion] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36759) sur ce problème dans GCC bugzilla. –

Questions connexes