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

Boost C++ Discussion :

Sérialisation d'un vecteur de int* avec Boost


Sujet :

Boost C++

  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Par défaut Sérialisation d'un vecteur de int* avec Boost
    Bonjour,

    Je suis en train de découvrir la partie séarization de Boost. D'après la doc, je peux séraliser les membres listes dans une classes, bien sûr avec les entêtes appropriées (ici #include <boost/serialization/list.hpp> )

    Voici mon code


    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
     
    #include <fstream>
     
    // include headers that implement a archive in simple text format
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
     
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
    #include <boost/serialization/list.hpp>
     
     
    /////////////////////////////////////////////////////////////
    // gps coordinate
    //
    // illustrates serialization for a simple type
    //
    class gps_position
    {
    private:
        friend class boost::serialization::access;
        // When the class Archive corresponds to an output archive, the
        // & operator is defined similar to <<.  Likewise, when the class Archive
        // is a type of input archive the & operator is defined similar to >>.
    	std::list< int* > list;
    	template<class Archive>
     
    	void serialize(Archive & ar, const unsigned int version)
        {
            ar & BOOST_SERIALIZATION_NVP( degrees );
            ar & BOOST_SERIALIZATION_NVP( minutes );
            ar & BOOST_SERIALIZATION_NVP( seconds );
    		ar & BOOST_SERIALIZATION_NVP( list );
        }
        int degrees;
        int minutes;
        float seconds;
     
    public:
        gps_position(){};
    	gps_position(int d, int m, float s, std::list< int* > v) :
            degrees(d), minutes(m), seconds(s), list( v )
        {}
    };
     
    int main() {
        // create and open a character archive for output
    	std::ofstream ofs("C:/Temp/nam.txt");
     
        // create class instance
    	std::list< int* > v;
    	v.push_back( new int( 1 ) );
    	v.push_back( new int( 2 ) );
        gps_position g(35, 59, 24.567f, v);
     
        // save data to archive
        {
            boost::archive::xml_oarchive oa(ofs);
            // write class instance to archive
            oa << BOOST_SERIALIZATION_NVP( g );
        	// archive and stream closed when destructors are called
        }
     
        // ... some time later restore the class instance to its orginal state
        gps_position newg;
        {
            // create and open an archive for input
            std::ifstream ifs("C:/Temp/nam.txt");
            boost::archive::xml_iarchive ia(ifs);
            // read class state from archive
            ia >> BOOST_SERIALIZATION_NVP( newg );
            // archive and stream closed when destructors are called
        }
        return 0;
    }

    Par contre, le programme ne compile pas avec le message d'erreur suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    1>main.cpp
    1>c:\devtools\boost\boost_1_37_0\boost\serialization\access.hpp(109) : error C2228: left of '.serialize' must have class/struct/union
    Merci pour vos aides

  2. #2
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    ton boost est *vraiment* un 1.37 ?
    Si oui, upgrade , on est a la 1.47

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 39
    Par défaut
    Salut Hibou,

    Il est impossible de sérializer directement un pointeur vers un type builtin, tel que int*. boost::serialization ne sait que serialiser des pointeurs de struct ou classe. Il faut donc mettre int dans un wrapper léger agissant comme un int (constructor prenant un int comme argument, operator int pour le transtypage), et utiliser des int_wrapper* plutôt que des int*. Boost définit la macro BOOST_STRONG_TYPEDEF( TYPE, WRAPPER ), qui te permet de définir un tel wrapper sans se prendre la tête.
    Après avoir défini ce wrapper, il ne faut pas oublier de définir un serialize() pour ce dernier.
    Cela donne donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    BOOST_STRONG_TYPEDEF( int, tracked_int )
    template <class T>
    void serialize( T& ar, tracked_int& my_int, unsigned int const )
    { ar & (int&)my_int; }
    Avec ensuite ton code utilisant des tracked_int* plutôt que des int*.
    Donc, pour ton code, cela donnerait :
    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
    #include <fstream>
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/archive/xml_oarchive.hpp>
    #include <boost/archive/xml_iarchive.hpp>
    #include <boost/serialization/list.hpp>
     
    BOOST_STRONG_TYPEDEF( int, tracked_int )
    BOOST_CLASS_IS_WRAPPER( int )
    template <class T>
    void serialize( T& ar, tracked_int& my_int, unsigned int const )
    { ar & (int&)my_int; }
     
    class gps_position
    {
    	private:
    		friend class boost::serialization::access;
    		template<class Archive>
    		void serialize(Archive & ar, const unsigned int)
    		{
    			ar & BOOST_SERIALIZATION_NVP( degrees );
    			ar & BOOST_SERIALIZATION_NVP( minutes );
    			ar & BOOST_SERIALIZATION_NVP( seconds );
    			ar & BOOST_SERIALIZATION_NVP( list );
    		}
    		int degrees;
    		int minutes;
    		float seconds;
    		typedef std::list<tracked_int*> list_type;
    		list_type list;
    	public:
    		gps_position(void) {};
    		gps_position(int d, int m, float s, list_type v) :
    				degrees(d), minutes(m), seconds(s), list(v) {}
    };
     
    int main(void) 
    {
    	std::ofstream ofs("/home/ether/a/temp");
    	std::list<tracked_int*> v;
    	v.push_back( new tracked_int( 1 ) );
    	v.push_back( new tracked_int( 2 ) );
    	gps_position g(35, 59, 24.567f, v);
    	{
    		boost::archive::xml_oarchive oa(ofs);
    		oa << BOOST_SERIALIZATION_NVP( g );
    	}
    	gps_position newg;
    	{
    		std::ifstream ifs("/home/ether/a/temp");
    		boost::archive::xml_iarchive ia(ifs);
    		ia >> BOOST_SERIALIZATION_NVP( newg );
    	}
    	return 0;
    }
    J'ai rajouté BOOST_CLASS_IS_WRAPPER parce que j'avais un message d'erreur sans (et seulement avec les archives xml, pas les archives text), mais je comprends pas vraiment pourquoi :-|, et je crois pas que ce soit la bonne chose à faire (c'est juste que ça semble corriger le problème)

  4. #4
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    153
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 153
    Par défaut
    Merci bien, c'est exactement la réponse que j'attends!

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/09/2009, 22h41
  2. [Servlet/JSP] - Pb de int avec un Bean d'un Servlet a un JSP
    Par ShinJava dans le forum Servlets/JSP
    Réponses: 15
    Dernier message: 09/07/2005, 00h41
  3. probleme de compilation avec boost
    Par doof dans le forum Bibliothèques
    Réponses: 7
    Dernier message: 07/06/2005, 21h38
  4. Calculer un inverse de matrice avec boost?
    Par Clad3 dans le forum Bibliothèques
    Réponses: 6
    Dernier message: 02/06/2005, 18h38
  5. probleme avec boost et devcpp
    Par Krost dans le forum Dev-C++
    Réponses: 12
    Dernier message: 02/01/2005, 19h11

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