IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Fortran Discussion :

Mélange Fortran et C


Sujet :

Fortran

  1. #1
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Par défaut Mélange Fortran et C
    Hello,
    Je précise davance, je connais pas le fortran (enfin je découvre depuis hiers)...
    J'ai donc récupéré un programme fortran relativement long. Dedan il y a une fonction qui m'interesse et que je souhaiterai pouvoir appeler a partir d'un code C.
    Première question:
    Sur ce lien:
    http://www.nersc.gov/nusers/resource...m/c_and_f.html
    On donne des exemples d'appel de C a partir du fortran et vice versa. L'édition des liens se fait avec soit un compilateur C, soit un fortran, selon le cas. Or moi je souhaite pouvoir a la fois appeler des routines fortran a partir du C, et des fonctions C a partir du fortran le tout dans un même programme. Donc première question, est-ce possible, et puis-je utiliser indifférement l'un des deux compilateurs? (ce qui me parait fort peu probable) Et si non, comment faire?

    Ensuite, la routine principale fortran que je souhaite appeler prends en paramètres des tableaux de double, matrices, des structures (ou l'équivalent fortran...), des fonctions (enfin ds pointeurs de fonction je suppose) et des arguments optionnels...
    Là dessu, sur les structures, pointeurs de fonction et stt sur les arguments optionnels, je souhaiterai savoir si c'est possible d'appeler ce genre de fonction à partir d'un programme C (pour les détails techniques je chercherai plus tard), histoire que je ne perde pas mon temps a essayer de faire quelque chose d'impossible...

    Voila (pour l'instant )
    Merci d'avance

  2. #2
    Membre averti
    Profil pro
    stagiaire
    Inscrit en
    Octobre 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : stagiaire

    Informations forums :
    Inscription : Octobre 2005
    Messages : 20
    Par défaut
    1. Il est tout a fait possible de mélanger le C et le fortran !

    2. génralement dans le source C il faut rajouter un _ (underscore) dans le nom des subroutine fortran que tu appeles.

    3. Je te conseille de compiler chaque fichier avec le compilateur associé au language et d'utiliser pour le link l'editeur de lien fortran en rajoutant un option pour indiquer que le main est en C ( exemple pour ifort => -norformain). sinon essayer avec le linker C.
    explication :
    pour l'instant un main en C et fonction fortran est possible mais plus pour longtemps.
    pour s'execute le C n'a pas besoin de runtime, le fortran non plus mais le C++ oui.
    Le Fortran aura bientot besoin d'un runtime pour cause des évolutions objets et pour lancer ce runtime le main devra obligatoirement etre dans un fichier fortran.
    Donc creation d'un main fortran qui appelle l'ancien main du C.

    Tiens moi au courant de tes tests
    @+

  3. #3
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Par défaut
    Pour être plus précis, du programme C j'appèlerai normalement uniquement une fonction qui retourne une structure contenant pas mal de chose.
    A cette fonction fortran, je donnerais un pointeur sur fonction qui devrait appeler une fonction qui elle seraié écrite en C... Voila les deux intéractions principales.

    En me fiant aux exemple que j'ai vu dans le lien indiqué, je fais un test bidon déja pr voir si j'arrive a faire les appels. Je souligne que je dois utiliser des bibliotheques de GSL et quelques fichiers minimaux, dc je les inclus dirèctement pr mes premiers tests. J'en suis donc là:
    C:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    extern void __dde_NMOD_essai_(double*, double*, double *, int *, int *, double (*fct)(double*)) ;
    extern void essai_(double*, double*, double *, int *, int *, double (*fct)(double*)) ;
    extern void essai(double*, double*, double *, int *, int *, double (*fct)(double*)) ;
     
    double fct(double *x) {
    	return (*x)*(*x) ;
    }
     
    int main(int argc, char **argv){
    	printf("\n\n- Program %s begins- \n\n", argv[0]);
    	double t ;
    	double y[] = {1.0, 2.0, 3.0} ;
    	double dy[] = {0., 0., 0.};
    	int neqn = 3. ;
    	int nlag = 3. ;
     
    	__dde_NMOD_essai_(&t, y, dy, &neqn, &nlag, &fct) ;	
    	essai(&t, y, dy, &neqn, &nlag, &fct) ;
    	essai_(&t, y, dy, &neqn, &nlag, &fct) ;
     
    	printf("\n\n- End of %s - \n\n", argv[0]);
     
    	return 0 ;
    }
    Fortran:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    MODULE dde
      IMPLICIT NONE
      CONTAINS
     
      SUBROUTINE ESSAI(T,Y,DY,NEQN,NLAGS,FCT)
          INTERFACE
    	  DOUBLE PRECISION FUNCTION FCT(T)  
                  DOUBLE PRECISION, INTENT(IN) :: T
              END FUNCTION FCT
          END INTERFACE
     
          ! DOUBLE PRECISION, EXTERNAL :: FCT
          INTEGER :: I, NEQN, NLAGS
          DOUBLE PRECISION :: T
          DOUBLE PRECISION, DIMENSION(NEQN) :: Y,DY
     
          INTENT(IN)  :: T,Y,NEQN,NLAGS
          INTENT(OUT) :: DY
     
          DY(1) = FCT(T+1.0D0)
     
          RETURN
      END SUBROUTINE ESSAI
    END MODULE dde
    Makefile:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    #------------------------------------------------------------
    # Makefile. Auteurs: Vince
    #------------------------------------------------------------
     
    PATH_GSL    = /home/vince/gsl-1.9/
    PATH_OBJ    = obj/
    PATH_SCR    = src/
    PATH_HEADER = headers/
    PATH_BIN    = bin/
     
    PROG        = dde
    CC          = gcc
    FCC         = gfortran
     
    CFLAGS      = -Wall -Wextra -Wwrite-strings -Wstrict-prototypes -D MD_OS_LINUX -I$(PATH_GSL)include
    LFLAGS	    = -L$(PATH_GSL)lib -lm -lgsl -lgslcblas 
     
    OBJ = $(PATH_OBJ)main.o $(PATH_OBJ)utils.o $(PATH_OBJ)dde.o $(PATH_OBJ)essaI.o
     
    #------------------------------------------------------------
    # REGLE GENERALE DE COMPILATION
    #------------------------------------------------------------
     
    $(PATH_OBJ)%.o: $(PATH_SCR)%.c $(PATH_HEADER)%.h
    	$(CC) $(CFLAGS) -c $< -o $@
     
    $(PATH_OBJ)%.o: $(PATH_SCR)%.f90
    	$(FCC) -c $< -o $@
     
    #-----------------------------------------------------------
    # REGLE POUR L'EXECUTABLE
    #-----------------------------------------------------------
     
    $(PATH_BIN)$(PROG): $(OBJ)
    	$(CC) $(LFLAGS) $^ -o $@
     
    #-----------------------------------------------------------
    # DEPENDANCES
    #-----------------------------------------------------------
     
    $(PATH_OBJ)main.o: $(PATH_HEADER)main.h $(PATH_HEADER)utils.h $(PATH_HEADER)dde.h
    $(PATH_OBJ)dde.o: $(PATH_HEADER)dde.h $(PATH_HEADER)utils.h
    $(PATH_OBJ)utils.o: $(PATH_HEADER)utils.h
    A l'édition des liens:
    gcc -L/home/vince/gsl-1.9/lib -lm -lgsl -lgslcblas obj/main.o obj/utils.o obj/dde.o obj/essaI.o -o bin/dde
    obj/main.o: In function `main':main.c.text+0x99): undefined reference to `__dde_NMOD_essai_'
    :main.c.text+0xc8): undefined reference to `essai'
    :main.c.text+0xf7): undefined reference to `essai_'
    collect2: ld returned 1 exit status
    Bref ca marche pas ^^ aucun des prototypes ne passe, je continue mes recherches, tout commentaire est le bienvenu..

  4. #4
    Membre averti
    Profil pro
    stagiaire
    Inscrit en
    Octobre 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : stagiaire

    Informations forums :
    Inscription : Octobre 2005
    Messages : 20
    Par défaut
    j'ai réutilisé a compilé ton exemple avec quelques modifications :

    1. j'ai utilisé ifort a la place de gfortran
    2. pour gcc j'ai forcé la compilation en 32 bits -m32 ; pas besoin pour le fortran
    3. dans dde.f90 j'ai supprimé le module et est declaré directement une subroutine dde
    4. dans main j'appelle dde_
    5. les pointeurs sur fonctions pas sur que ca marche.

    Je peux pas plus t'aider
    mais tiens moi au courant de tes investigations et conclusion sur l'utilisations des modules et des pointeurs sur fonctions.

    A+
    Fabrice

  5. #5
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Par défaut
    Ok ca marche de mon coté, en revanche j'ai juste retiré les histoires de modules... Ce qui est assez embettant car le programme que j'ai récupéré est quelque peu complexe et la fonction que je veux appeler est déclarée ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      ! .. Generic Interface Blocks ..
      INTERFACE DDE_SOLVER
         MODULE PROCEDURE DKL_1, DKL_2, DKL_3, DKL_4, ODEAVG
      END INTERFACE
    Ce qui me trouble c'est que j'ai pas trouvé de déclaration de type FUNCTION DDE_SOLVER ou SUBROUTINE DDE_SOLVER dans le fichier...

    En tout cas pparamaent l'option -m32 n'est pas necessaire (du moins pr l'exemple présent) et le copilateur que j'utilise a la base fonctionne également.

    Pour le pointeur de fonction, ca semble fonctionner (je met un 'coucou' dans la fonction fct et il apparait bien). Je vas continuer histoire de voir que les valeurs collent bien etc... et je passerait aux structure & aux arguments optionnels je sens que ca va etre prise de tête...

    En tt cas merci a toi

  6. #6
    Membre averti
    Profil pro
    stagiaire
    Inscrit en
    Octobre 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : stagiaire

    Informations forums :
    Inscription : Octobre 2005
    Messages : 20
    Par défaut
    pour l'histoire des modules , tu as la réponse ici : http://www.developpez.net/forums/sho...d.php?t=311098

  7. #7
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Par défaut
    Ca passe pas, c'est peut être spécifique au c++...
    EDIT: Enfin je dit que ca passe pas ms j'ai pas encore testé la première méthode

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Par défaut
    Citation Envoyé par vinzzzz
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      ! .. Generic Interface Blocks ..
      INTERFACE DDE_SOLVER
         MODULE PROCEDURE DKL_1, DKL_2, DKL_3, DKL_4, ODEAVG
      END INTERFACE
    Ce qui me trouble c'est que j'ai pas trouvé de déclaration de type FUNCTION DDE_SOLVER ou SUBROUTINE DDE_SOLVER dans le fichier...
    Tu n'en trouveras pas. Ce que dit le bout de code, c'est que DDE_SOLVER est une fonction ou routine générique. Les fonctions spécifiques étant fournies par la ligne MODULE PROCEDURE. La selection de la fonction ou routine spécifique étant résolue par le nombre et le type des arguments.

    Par exemple, quand tu fais CALL DDE_SOLVER(real), le compilateur utilisera la routine de la liste dont l'argument est real.

  9. #9
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Par défaut
    Merci pour cette précision

Discussions similaires

  1. Problème en interfacant C et Fortran
    Par karl3i dans le forum MFC
    Réponses: 6
    Dernier message: 23/05/2006, 16h10
  2. Compilateur Fortran
    Par badrou dans le forum Fortran
    Réponses: 3
    Dernier message: 28/11/2004, 20h39
  3. accès fortran à une base / utilisation des "bytea"
    Par bdkiller dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 05/11/2004, 08h31
  4. Simulateur fortran
    Par kaczmarek dans le forum Linux
    Réponses: 1
    Dernier message: 28/07/2004, 17h55
  5. [TP]Portage d'un encodeur MP3 Fortran en pur Pascal...
    Par Christophe Fantoni dans le forum Turbo Pascal
    Réponses: 11
    Dernier message: 04/07/2003, 17h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo