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

C++ Discussion :

petit problème avec ma librairie c++


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 33
    Par défaut petit problème avec ma librairie c++
    j'ai un léger problème avec ma librairie c++

    voici ma classe

    // fichier h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Log
    {
    public:
      void Print (const std::wstring& text);
     
      static void Open (const std::string& filename);
     
      static Log& Instance ();
     
    private:
      Log () {}
     
      std::wofstream out;
    };
    // fichier cpp
    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
    void Log::Open (const std::string& filename)
    {
       Instance ().out.open (filename.c_str ());
    }
     
    Log& Log::Instance ()
    {
      static Log log;
      return log;
    }
     
    void Log::Print (const std::wstring& txt)
    {
      out << txt;
    }

    voici les option que j'utilise pour la créer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    gcc -c Log.cpp
    ar rcs liblog.a Log.o
    voici un extrait du programme qui l'utilise:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main (....
    {
      Log::Open ("Essai.txt")
      Log& log = Log::Instance ();
     
      log.Print (L"Dans main");
    .
    .
    .

    et les options pour le compiler:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    gcc -c Log.cpp
    ar rcs liblog.a Log.o
    gcc -o test Main.cpp -LdirectoryMyLibray -lstdc++ -llog
    quand j'exécute le programme, le fichier essai.txt est créé, mais il n'y a rien d'écris dedans

    j'ai ensuite rajouté une autre classe en dessous de l'autre:

    // fichier h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Log2
    {
    public:
      void Print (const std::wstring& text);
      void Open (const std::string& filename);
     
    private:
      std::wofstream out;
    };
    // fichier cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Log2::Open (const std::string& filename)
    {
      out.open (filename.c_str ());
    }
     
    void Log2::Print (const std::wstring& txt)
    {
      out << txt;
    }
    le fichier main:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    .
    .
    .
      Log2 l;
      l.Open ("Essai2.txt");
      l.Print (L"Dans main");
    J'ai recompilé avec les mêmes option

    La classe Log2 ouvre le fichier et cette fois imprime bien le texte "Dans Main"

    mais Log qui est une classe Singleton ne fonctionne pas, il n'y a rien d'écrit dans son fichier (qui a bien été créé, mais qui reste vide).

    Y a t'il d'autres option à définir pour le compilateur pour la faire fonctionner correctement ?

    sur Visual C++ cela fonctionne correctement

  2. #2
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 33
    Par défaut
    j'en ai fait une librairie partagée, j'ai toujours le même problème

    dois je utiliser g++ à la place de gcc, ou ils sont identiques ?

  3. #3
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Ton code compile ?
    Chez moi ça ne compile pas !

    Tu as une fonction membre static "Open" qui accede à une donnée membre non static "out".

    En la mettant non static ça fonctionne.

    Dans ton deuxieme code tu l'as bien mise non static.

  4. #4
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 33
    Par défaut
    oui, tu a raison, mais c'est une faute que j'ai faite ici, en entrant le texte pour ma classe, j'ai corrigé la fonction Print statique pour qu'elle appelle la fonction Instance statique pour recevoir out de l'unique instance du singleton. (comme elle l'est dans mon code)

  5. #5
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 33
    Par défaut
    voila, j'ai réécrit mes classes pour mieux voir le problème, je les replaces ici, en enlevant les informations qui sont pas utiles, comme les définitions #ifndef en début de fichier include, espace de nom, ...:

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    //fichier convertingStrings.h (nécessaire pour convertire une wstring en string):
     
    #include <string>
    const std::wstring StringToWString (const std::string& s)
    {
      std::wstring temp (s.length (), L' ');
      std::copy (s.begin (), s.end (), temp.begin ());
      return temp;
    }
     
     
    const std::string WStringToString (const std::wstring& s)
    {
      std::string temp (s.length (), ' ');
      std::copy (s.begin (), s.end (), temp.begin ());
      return temp;
    }
     
    ---------------------
     
    fichier Log.h
     
    #include <fstream>
    #include <string>
    #include <iostream>
     
    class Log
    {
    public:
      // La commande pour imprimer le texte.
      void Print (const std::wstring& wtext, const std::string& text);
     
      // La fonction pour ouvrir un fichier.
      static void Open (const std::wstring& wfilename, const std::string& filename);
     
      // Les fonctions d'accès pour recevoir une référence ou un pointeur sur l'unique instance de cette classe.
      static Log& Reference ();
      static Log* Pointer   () { return &Reference (); }
     
    private:
      // Constructeur et destructeur
       Log () {}
      ~Log () {}
     
      // Interdit la construction par copie et l'assignation
     
      Log& operator= (Log&);
     
      Log (const Log&);
     
     
      std::wofstream wout;   // Le flux de sortie sur lequel écrire.
      std::ofstream  out;   
    };
     
    -----------------
     
    fichier log.cpp
     
    #include "Log.h"
    #include "ConvertingStrings.h"
     
    // La fonction statique pour ouvrir un fichier.
    void Log::Open (const std::wstring& wfilename, const std::string& filename)
    {
      Log& log = Reference ();
     
      log.wout.open (WStringToString (wfilename).c_str ());
      log.out.open (filename.c_str ());
    }
     
    // La fonction statique pour obtenir une référence sur la seule instance de cette classe.
    Log& Log::Reference ()
    {
      static Log log;
     
      return log;
    }
     
    // La fonction pour écrire sur le flux
    void Log::Print (const std::wstring& wtext, const std::string& text)
    {
      wout << wtext << std::endl;
      out  << text  << std::endl;
    }
     
    --------------------
     
    Main.cpp:
    #include "Log.h"
     
    int main (int argc, char *argv[])
    {
      Log::Open (L"Wessai.txt", "essai.txt");
     
      Log::Reference().Print (L"Appellée dans main à partir de la référence.", "Appellée dans main à partir de la référence.");
      Log::Pointer()->Print (L"Appellée dans main à partir du pointeur.", "Appellée dans main à partir du pointeur.");
     
      return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Les commandes utilisées pour construire la librairie:
    gcc -c Log.cpp  
    ar rcs libstatique.a Log.o
     
    // Commande pour créer l'application
    gcc -o test Main.cpp -L/home/philippe/statique -lstdc++ -lstatique
    J'ai aussi modifié ma classe pour écrire en même temps sur un ofstream et wofstream
    quand j'exécute cette application, les fichiers essai.txt et wessai.txt sont créés, mais wessai.txt reste désespérément vide, alors que le fichier essai est bien remplit avec:

    Appellée dans main à partir de la référence.
    Appellée dans main à partir du pointeur.

    Il doit y avoir un bug avec wstring et wofstream sur linux, mais je ne sais pas quel bug c'est. Je ne sais pas s'il y a un moyen ou pas de contourner ce bug. Je me demandais depuis quelques jours pourquoi certains moteurs graphiques 3D utilisant unicode définissaient leurs propres class STRING, maintenant je pense avoir deviné pourquoi ^^. Ce bug existe uniquement sur Linux, cela fonctionne bien sur la dernière versions de Visual C++ sous Windows. J'utilise la dernière version d'OpenSuse

    j'ai fait quelques essais supplémentaires, j'ai rajouté une fonction dans log
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void Print (int i)
    {
      wout << i << std::endl;
      out  << i << std::end;
    }
    Avant les deux fonctions Print qui sont dans main, j'ai rajouté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Log::Reference ().Print (4);
    Log::Reference ().Print (5);
    Log::Reference ().Print (6);
    Après les deux fonctions Print dans main, j'ai rajouté:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Log::Reference ().Print (7);
    Log::Reference ().Print (8);
    Log::Reference ().Print (9);
    dans le fichier essai.txt, j'ai:
    4
    5
    6
    Appellée dans main à partir de la référence.
    Appellée dans main à partir du pointeur.
    7
    8
    9

    dans le fichier wessai.txt, j'ai seulement:
    4
    5
    6

  6. #6
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 33
    Par défaut
    J'ai trouvé la cause du problème. Il faut définir la bonne locale pour le wofstream. Par défaut, la locale est définir à "C", faut la définir pour le français.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void Log::Open (const std::wstring& wfilename)
    {
      Log& log = Reference ();
      log.wout.open (WStringToString (wfilename).c_str ());
      const char* language = getenv ("LANG");
      log.wout.imbue(std::locale(language));
    }
    La solution fonctionne, mais ne me plait pas encore, j'obtient la locale actuelle de l'ordinateur en la récupérant avec getenv et la variable d'environnement LANG, mais cette variable n'est pas définie sur Windows, et je sais pas si elle est définie sur toutes les distributions Linux, j'ai posté un nouveau sujet sur le forum C, pour demander comment recevoir la locale de l'ordinateur pour essayer d'avoir une solution portable

    ce qui est bizarre, c'est que out et cout sont aussi définie à la locale pour le langage "C", mais out et cout imprimait correctement mon texte, alors que wofstream ne le faisait pas

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec la librairie POI
    Par clement42 dans le forum Documents
    Réponses: 3
    Dernier message: 18/11/2005, 19h11
  2. (Petit ?) problème avec une page contenant du Flash
    Par ologram dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 01/09/2005, 18h45
  3. Petit problème avec SDL
    Par Nyarlathotep dans le forum C
    Réponses: 10
    Dernier message: 01/07/2005, 09h10
  4. Problème avec la librairie rfunc sous Firebird
    Par yayelix dans le forum SQL
    Réponses: 4
    Dernier message: 17/05/2005, 16h49
  5. Problème avec les librairies ZLIB et LIBPNG
    Par VenusX117 dans le forum Bibliothèques
    Réponses: 1
    Dernier message: 14/03/2005, 14h49

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