Tout d'abord, je tiens à préciser que ces explications ne viennent que de sombres pratiques expérimentales. Il est possible que cela ne fonctionne pas pour vous: différences de version pour l'OS ou les compilateurs. J'utilise une SuSE 6.1 de base, avec le compilateur g77 d'origine. (les versions précédentes de cette page parlaient de f2c, que j'ai abandonné)
Il suffit de compiler un programme Fortran avec une fonction non définie pour se rendre compte que g77 passe les nom de fonction en minuscules, et leur ajoute un underscore à la fin. Il me semble que ce comportement peut être modifié par des options données au translateur.
Essentiellement, nous allons avoir un passage de paramètres par référence.
C'est à dire que g77
va transmettre un pointeur sur les données
à la fonction en C
.
Cela permet à la fonction appelée de modifier une variable appartenant à l'appelant.
Voyons dont un premier exemple, très simple:
integer RET,A,B integer somme A = 2 B = 3 RET = somme(A,B) write (6,2) RET 2 format(1X, '2 + 3 = ', I4) end |
int somme_(int *pa, int *pb) { int foo; foo = *pa + *pb; return foo; } |
Cela semble simple ? Quand même un petit piège: puisque le nom que j'ai choisi pour ma fonction ne commence pas par les "lettres entières" magiques du fortran (IJKLMN), il convient de déclarer son type, INTEGER dans notre cas.
... vont nous poser quelques problèmes. En effet, g77 n'utilise probablement pas le format ASCIIZ du langage C, mais plus probablement des chaines à taille constante. Utilisons une fois de plus la méthode expérimentale.
character*10 CHAINE write (6,1) 1 format (1X,'variable') CHAINE = 'foobar' call DUMP(CHAINE) write (6,2) 2 format (1X,'constante') call DUMP('foobar') end |
void dump_(unsigned char *ptr) { int foo; for (foo=0; foo<16; foo++) { printf("%02x ", ptr[foo]); } printf("\n"); } |
titi@leon ~/fortrash/ $ ./essai variable 66 6f 6f 62 61 72 20 20 20 20 00 00 09 04 00 00 constante 66 6f 6f 62 61 72 00 25 30 32 78 20 00 0a 00 00 |
Dans le premier cas, nous constatons que l'affectation d'une constante à une variable complète la zone disponible avec des espaces. Et dans le second, il semble que la constante-chaine soit effectivement terminée par un '\0', mais bon, ymmv. Nous voici donc confronté à trois possibilités: