Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1434 connectés 

  FORUM HardWare.fr
  Programmation
  Divers

  Appel à une fonction C++ à partir du fortran

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Appel à une fonction C++ à partir du fortran

n°848844
nathan_g
Posté le 13-09-2004 à 15:29:01  profilanswer
 

Bonjour,
 
Je souhaiterais pouvoir appeler une fonction écrite en C++ à partir d'un programme fortran. Je pensais savoir comment faire et, d'habitude, cela marchait mais là, je ne vois pas ce qui pose problème. Pour simplifier, mon programme fortran principal est :
 
principal.f :
 
      program principal
 
      integer carre
 
      integer a
 
      a=3
 
      print *,"carre=",carre(a)
       
      end program
 
et la fonction " carre " écrite en C++ est dans le fichier Carre.C :
 
#include <fstream.h>
 
extern "C" int carre_(int*);
 
int carre_(int* b)
{
  int c;
   
  c = (*b)*(*b);
   
  cout << "c = " << c << endl;
 
  return (c);  
}
 
Je compile succsessivement par :
 
g77 -c principal.f
g++ -c Carre.C
g77 -o principal principal.o Carre.o
 
A l'édition de lien, j'ai un message d'erreur m'indiquant que les opérateurs cout, << et endl ne sont pas connus (alors que la bibliothèque fstream.h est la pourt ça). Apparemment, c'est le seul problème car, lorsque j'évite de faire une sortie écran de la valeur de c, le programme fonctionne. Qu'est ce qui cloche ? Comment obliger le programme à faire ces sorties écran ?
 
D'avance merci de votre aide  
 
Nathan G
 

mood
Publicité
Posté le 13-09-2004 à 15:29:01  profilanswer
 

n°848872
Lam's
Profil: bas.
Posté le 13-09-2004 à 16:04:57  profilanswer
 

Essaye de rajouter libstdc++.a à ta ligne de link (la dernière donc), ou au pire, le paramètre "-lstdc++".
 
Sinon, 2 remarques :  
1. c'est du vieux c++ que tu nous fais là. La norme a un peu changé depuis 99, on y reviendra plus tard.
 
2. fstream.h n'est pas une bibliothèque mais un fichier de déclarations : tu déclares les fonctions (leurs signatures), mais tu ne les définis pas (tu ne donnes pas leurs implémentations). Tout ça se trouve dans ... libstdc++, tu l'avais deviné. :)
 
 
Edit: non, comme d'hab, je dis plein de conneries. En fait, utilise plutot "g++" pour faire le link, plutôt que "g77". Ca devrait peut-être mieux marcher :-)


Message édité par Lam's le 13-09-2004 à 16:06:02
n°848898
nathan_g
Posté le 13-09-2004 à 16:18:09  profilanswer
 

Merci bcp, ca fonctionne maintenant !
 
Juste quelques explications supplémentaires. Si les définitions des opérateurs posant problème (cout,endl,<< ...) se trouvent dans le fichier libstdc++.a, pourquoi faut-il rajouter ce fichier dans la ligne de compilation avec g77, c'est à dire le compiler en plus de mes propres fichiers *.o, alors que cela est inutile si j'utilise g++. Est ce justement parce que cette librarie est standard en c++ et donc inutile à indiquer lors s'une compilation purement en c++ ?

n°848914
Lam's
Profil: bas.
Posté le 13-09-2004 à 16:28:11  profilanswer
 

nathan_g a écrit :

Est ce justement parce que cette librarie est standard en c++ et donc inutile à indiquer lors s'une compilation purement en c++ ?


 
Oui, c'est la "Standard Library" définie par le standard C++. Pour g++, elle s'appelle libstdc++. Pour Forte sous Solaris, elle s'appelle libC.  
Et donc, bien sûr, le compilateur sait généralement qu'il faut l'inclure.  
 
Maintenant, tu vas me faire plaisir, et remplacer
#include "fstream.h" par #include <fstream>
 
Et juste après la dernière ligne d'include, tu écris:
   using namespace std;
 
Ca te fera rééllement basculer dans le C++ du 3ème millénaire ;-)

n°848939
nathan_g
Posté le 13-09-2004 à 16:47:26  profilanswer
 

Dernière question (je sais j'insite).
 
J'ai un peu regardé sur le forum pour comprendre l'intérêt du "using namespace std".
 
En fait les commandes cout , endl ... devraient s'écrire std::cout et std::endl. La ligne "using namespace std" permet de raccourcir ces commandes en signifiant qu'elles sont du même type. C'est ça ?
 
Néanmoins, comme tu le vois, je l'oublie systématiquement. Ce n'est pas grave car, par défaut, il est rajouté ?
 
Mais, si j'ai d'autres commandes faisant parties du même contexte (par ex toto), je peut aussi utiliser une seconde commande using namespace toto ? Dans ce cas, on peut aussi surcharger les commandes cout, endl (je sais, ce serait pousser le bouchon). En fait, il n'y pas de risuqe de confusion ? Le programme sait dans quel namespace se situe chaque commande ?

n°848971
Lam's
Profil: bas.
Posté le 13-09-2004 à 17:16:22  profilanswer
 

nathan_g a écrit :


En fait les commandes cout , endl ... devraient s'écrire std::cout et std::endl. La ligne "using namespace std" permet de raccourcir ces commandes en signifiant qu'elles sont du même type. C'est ça ?


 
En C++, tu as des namespaces (package/librairies/nom de domaine, enfin tu vois le genre).  
 
Le fichier <fstream> est défini comme:  
 
namespace std {
#include <fstream.h>
}
 
Donc, si tu utilises fstream (ce qui est largement recommandé), plutôt que fstream.h (qui est là pour la compatibilité ascendante), alors tes variables/types/méthodes seront définies dans le namespace std uniquement.
 
Pour t'en servir, tu as alors 3 choix possibles:
 
1. incorporer tout std, avec la ligne:
using namespace std;
 
2. incorporer uniquement cout avec:
using std::cout;
 
3: préciser à chaque fois que tu veux spécifiquement le cout de std:
std::cout << "Hello" << std::endl;
 
Ton code actuel fonctionne parce que tu utilises le vieux header, et donc tu n'as pas besoin d'incorporer std. Quand je dis incorporer std, cela signifie que tu indiques au compilo que tout ce qui se trouve dans std doit désormais être accessible depuis le namespace global (celui par défaut).
 
 
Enfin, pour n'utiliser que cout, etc. Pas besoin de <fstream> : tu devrais en fait inclure <iostream>
 
Et pour finir, ce que tu disais est globalement vrai:
 

Code :
  1. #include <iostream>
  2. // par défaut, on est dans le namespace global
  3. std::string endl = "GlobalEndl";
  4. namespace toto {
  5.   std::string endl = "TotoEndl";
  6. }
  7. int main() {
  8.   std::cout << endl << " " << toto::endl << std::endl;
  9.   return 0;
  10. }


 
Ceci devrait fonctionner et afficher "GlobalEndl TotoEndl".
 

n°848978
nathan_g
Posté le 13-09-2004 à 17:26:08  profilanswer
 

Malheureusement, à la compilation, j'ai :
 
g++ -c main.C
 
main.C:4: syntax error before `='
main.C:7: syntax error before `='
main.C: In function `int main()':
main.C:11: `endl' undeclared in namespace `toto'
 
Mais, j'ai, je crois un compilateur assez ancien. En plus, les fichiers de déclaration sont bizarrement positionné sur ma machine (par ex include <time> n'est pas accepté à la compilation mais include "time.h" l'est).
 
Enfin, je pense quand même avoir compris pas mal de chose sur le C++ grace à toi. Si je cherche d'autres précisions, j'essaierais de me plonger dans un bouquin sur le C++.
 
Merci pour tout !

n°848983
Lam's
Profil: bas.
Posté le 13-09-2004 à 17:31:58  profilanswer
 

nathan_g a écrit :


main.C:4: syntax error before `='
main.C:7: syntax error before `='
main.C: In function `int main()':
main.C:11: `endl' undeclared in namespace `toto'


 
Aaaargh.
J'ai oublié un #include <string> bien sûr !!!!
 
Mais bon, tu vois l'esprit. C'est juste pour que tu ne sois pas surpris si tu vois que ton code se marrie "mal" avec des programmes qui utilisent la norme C++ plutôt que la vieille façon de faire...

n°849019
SomeBugsIn​Me
life suxx
Posté le 13-09-2004 à 18:14:29  profilanswer
 

nathan_g a écrit :


Mais, j'ai, je crois un compilateur assez ancien. En plus, les fichiers de déclaration sont bizarrement positionné sur ma machine (par ex include <time> n'est pas accepté à la compilation mais include "time.h" l'est).


 
ben c'est #include <ctime> comme pour les autres headers C (<cstdio> etc...)

n°849659
nathan_g
Posté le 14-09-2004 à 09:00:58  profilanswer
 

Ah, OK, je vais essayer. Je ne savais pas. Merci !


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Divers

  Appel à une fonction C++ à partir du fortran

 

Sujets relatifs
Retrouver l'age à partir d'une date?Recherche une fonction [Réglé]
Pointeur de fonction en paramètrequitter proprement une application a partir d'une interface graphique
insertion dans une std::list à partir d'un reverse_iteratorFonction extract : portée ?
[Fortran] fichiers sortieDélai avant fonction cache()
fonction is_dir() qui buginput submit, onclick, fonction ???
Plus de sujets relatifs à : Appel à une fonction C++ à partir du fortran


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR