Passage d’un tableau en deux dimensions de Fortran à C

J’ai des difficultés à faire passer un tableau bidimensionnel de Fortran à C. Voici la fonction C qui affiche simplement les éléments du tableau à l’écran.

#include  void print2(double *arr , int *n) { int y = *n; printf("\ny = %d", y); for(int i =0; i<y; i++) { for (int j = 0; j < y; j++) printf("%.6g", *((arr + i*y) + j)); printf("\n"); } } 

Mon code Fortran jusqu’à présent est le suivant:

 program linkFwithC use, insortingnsic :: iso_c_binding implicit none real, dimension(3,3)::a a(1,1)=1 a(1,2)=2 a(1,3)=3 a(2,1)=4 a(2,2)=5 a(2,3)=6 a(3,1)=7 a(3,2)=8 a(3,3)=9 interface subroutine print2(a,n) bind( c ) use, insortingnsic :: iso_c_binding type(c_ptr)::a integer(C_INT)::n end subroutine print2 end interface call print2(c_loc(a),3) end program linkFwithC 

La façon dont je lie les deux fichiers consiste à créer une bibliothèque statique pour la fonction C et à générer le fichier .lib. Une fois le fichier .lib créé, je l’ajoute au projet fortran et lance le projet fortran. Le code fonctionne sans erreur et la valeur n est affichée correctement. Cependant, les valeurs de tableau affichées sont toutes fausses.

S’il vous plaît aider!

Merci, Anas

Il y a quelques problèmes dans le code comme indiqué [actuellement].

  • L’argument n dans l’interface Fortran pour print2 n’a pas l’atsortingbut VALUE, mais le paramètre correspondant dans la fonction C est pris par valeur. Envisagez d’append VALUE à la déclaration Fortran.

  • Le même problème se pose avec le pointeur sur le tableau. L’interface Fortran passe un pointeur sans valeur, la fonction C attend un “pointeur par valeur” (par opposition à un pointeur sur un pointeur). Notez qu’il n’est pas nécessaire d’utiliser explicitement un C_PTR ici – vous pouvez construire une interface interopérable en utilisant le type réel du tableau.

  • Sur la plupart des plates-formes, un REAL par défaut Fortran n’est pas identique à un C double: envisagez d’utiliser les constantes de type de ISO_C_BINDING pour vous assurer que le type de REAL côté Fortran correspond à celui du C.

  • C_LOC nécessite que son argument ait l’atsortingbut TARGET. Ajoutez cet atsortingbut à la déclaration de la variable a dans le programme principal.

Après d’autres recherches, j’ai pu trouver un travail autour de cela:

Ce qui suit est ma fonction C:

 #include  void print2(void *p, int n) { printf("Array from C is \n"); double *dptr; dptr = (double *)p; for (int i = 0; i < n; i++) { for (int j = 0; j 

Ce qui suit est mon code Fortran:

 program linkFwithC use iso_c_binding implicit none interface subroutine my_routine(p,r) bind(c,name='print2') import :: c_ptr import :: c_int type(c_ptr), value :: p integer(c_int), value :: r end subroutine end interface integer,parameter ::n=3 real (c_double), allocatable, target :: xyz(:,:) real (c_double), target :: abc(3,3) type(c_ptr) :: cptr allocate(xyz(n,n)) cptr = c_loc(xyz(1,1)) !Inputing array valyes xyz(1,1)= 1 xyz(1,2)= 2 xyz(1,3)= 3 xyz(2,1)= 4 xyz(2,2)= 5 xyz(2,3)= 6 xyz(3,1)= 7 xyz(3,2)= 8 xyz(3,3)= 9 call my_routine(cptr,n) deallocate(xyz) pause end program linkFwithC