Communication entre C et g77

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é)

Nommer la fonction C

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.

Passage des paramètres

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.

Les chaines de caractères

... 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:

La troisième hypothèse nous procure un nouveau mystère: ou est cachée la taille de cet espace ? Uts,l!.


 [HOME]   [oulala@chez.com]