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 :

[boost::serialization XML] problèmes de désserialisation


Sujet :

Boost C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut [boost::serialization XML] problèmes de désserialisation
    Boujours tout le monde.
    J'ai décidé d'utiliser boost::serialization XML pour enregistrer et sauvegarder les données de mon moteur 3D en C++ (pour voir ce que ça donne, une démo est ici en dernière page : http://www.developpez.net/forums/d72...rain-clipmaps/)

    Pour serialiser mes objets en XML pas de problème. J'ai suivie le tuto de dev eloppez à la lettre.
    C'est pour desserialiser que ça se corse:

    Suivant l'ordre des commandes d'enregistrement des cast possibles et des classe fille soit mon programme plante au moment du cast de mon pointeur soit j'ai une erreur de compilation

    j'utilise MSVC++ 2005 et boost 1.39 le tout sur Windows 7
    voici ma méthode de desserialisation:
    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
     
    void CChargeurDataXML::Charger(std::string i_strNom, boost::shared_ptr<CDataXML> & o_DataXML)
    {
        std::ifstream ifileXML(i_strNom.c_str());
        try 
        {
            boost::archive::xml_iarchive iTextArchiveXML(ifileXML);
    	    // inscription dans les tables Boost: CDataXML est la classe de base
            // camera hérite de CDataML
    	    iTextArchiveXML.register_type(static_cast<CCameraXML *>(NULL));
            boost::serialization::void_cast_register(static_cast<CCameraXML *>(NULL),static_cast<CDataXML *>(NULL));  
            // lumiere hérite de CDataML
    	    iTextArchiveXML.register_type(static_cast<CLumiereXML *>(NULL));
    	    boost::serialization::void_cast_register(static_cast<CLumiereXML *>(NULL),static_cast<CDataXML *>(NULL)); 
            // shader hérite de CDataML
    	    iTextArchiveXML.register_type(static_cast<CShaderXML *>(NULL));
    	    boost::serialization::void_cast_register(static_cast<CShaderXML *>(NULL),static_cast<CDataXML *>(NULL));
            // scene info hérite de CDataML
    	    iTextArchiveXML.register_type(static_cast<CSceneInfoXML *>(NULL));
            boost::serialization::void_cast_register(static_cast<CSceneInfoXML *>(NULL),static_cast<CDataXML *>(NULL)); 
            // CMediaXML hérite de CDataML, les CMediaTextureXML et autres héritent de CMediaXML
    	    iTextArchiveXML.register_type(static_cast<CMediaXML *>(NULL));
            boost::serialization::void_cast_register(static_cast<CMediaXML *>(NULL),static_cast<CDataXML *>(NULL)); 
     
    	    iTextArchiveXML.register_type(static_cast<CMediaTextureXML *>(NULL));
    	    boost::serialization::void_cast_register(static_cast<CMediaTextureXML *>(NULL),static_cast<CMediaXML *>(NULL)); 
        boost::serialization::void_cast_register(static_cast<CMediaTextureXML *>(NULL),static_cast<CDataXML *>(NULL)); 
    	    iTextArchiveXML.register_type(static_cast<CMediaTextureArrayXML *>(NULL));
       boost::serialization::void_cast_register(static_cast<CMediaTextureArrayXML *>(NULL),static_cast<CMediaXML *>(NULL)); 
    	    boost::serialization::void_cast_register(static_cast<CMediaTextureArrayXML *>(NULL),static_cast<CDataXML *>(NULL)); 
    	    iTextArchiveXML.register_type(static_cast<CMediaCubeMapXML *>(NULL));
    	    boost::serialization::void_cast_register(static_cast<CMediaCubeMapXML *>(NULL),static_cast<CMediaXML *>(NULL)); 
    	    boost::serialization::void_cast_register(static_cast<CMediaCubeMapXML *>(NULL),static_cast<CDataXML *>(NULL)); 
     
            CDataXML * l_pData = o_DataXML.get();
            iTextArchiveXML >> BOOST_SERIALIZATION_NVP(l_pData);     // déssérialisation
            o_DataXML = boost::shared_ptr<CDataXML>(l_pData);
        }
        catch(boost::archive::archive_exception & e)
        {
            std::cout << e.what();
        }
        ifileXML.close();
    }
    Le code ci dessus ne compile pas, erreur ci desous.
    EN enlevant les média ca compile mais ca plante à l'éxecution à cett endroit dans iserializer.hpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        static void invoke(Archive & ar, Tptr & t){
            const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t);
            const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer(
                * reinterpret_cast<void **>(&t),
                bpis_ptr,
                archive_pointer_iserializer<Archive>::find
            );
            // if the pointer isn't that of the base class
            if(newbpis_ptr != bpis_ptr){
                t = pointer_tweak(newbpis_ptr->get_eti(), t, *t);
            }
        }
    la méchante erreur de compilation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Erreur	3	error C2664: 'boost::archive::load_wrapper'*: impossible de convertir le paramètre 3 de 'boost::serialization::is_wrapper<T>' en 'boost::mpl::true_'	C:\COTS\boost_1_39\boost\archive\detail\iserializer.hpp	560
    Je n'ai pas mit tout le code: 2000 lignes ça fait beaucoup

    Pour résumer la serialisation marche parfaitement, c'est pour desserialiser que j'ai n'importe quoi. Un détail à du m'échapper mais je ne sais pas quoi.
    merci pour votre aide.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    Je reprend mon code pour voir ou est le problème.
    Première constatation il faut que les cast soient enregistré dans le même ordre et qu'ils soient identiques dans la méthode de sérialisation et dans celle de desserialisation: boost met dans le fichier XML des identifiants qui lui permet de retrouver le type des éléments XML manipulés.

    Sans les classe CMediaXML et dérivés je n'ai plus de problèmes donc mes ils viennent de ces classes je vais les reprendre petit à petit pour trouver les problèmes.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    J'ai trouvé! j'ai mis un des paramètres de mes classe à serialiser const , c'est ça qui posait problème à la compilation.

    Est ce qu'un expert boost aurai eu vent de ce problème?

    Je mettrai résolue dès que j'aurai terminer tout mes tests.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    J'ai maintenant un autre problème! Quand je desserialise mes CMediaXML les methode de serialisation/desserialisation sont bien appelé mais au final mes données ne sont pas prise en compte.
    Je pense que mes enregistrement de cast sont mauvais.

    comme j'ai des classe C qui héritent de CMediaXML qui hérite de CDataXML c'est un peu plus compliqué que ce que disent les tutos.

    Je mettrai le résultat, quand j'aurai trouvé

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    Je viens de résoudre mon dernier problème: Les données de mes classe meres étaient correctement sérialisées mais à la deserialisation je n'arrivais pas à les récupéré. Ce qui est plutôt génant:

    le mets ci dessous le code source qui marche pour compléter le tuto boost sur le sujet:
    Il comprend trois classes: C hérite de B qui hérite de A
    + le code pour sérialiser/dessérialiser avec les enregistrement de cast

    tout d'abord mes classe destiné à la serialisation/desserialisation
    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
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
     
    // les heider boost
    #include <boost/serialization/base_object.hpp>
    #include <boost/serialization/access.hpp>
    #include <boost/serialization/split_member.hpp>
     
    ///////////
    /// un truc perso et sans interet, je mets pour que ça compile ^^
    /////////////
    enum TypeXML
    {
        DEFAUT_XML,
        MODEL_XML,
        OBJET_XML
    };
     
     
    //////////////////////
    /// classe de base de toutes les données pouvant être chargé par fichier XML
    ///////////////////////
    class SYL_ENGINEXML_EXPORT CDataXML
    {
        friend class boost::serialization::access;
    public:
        CDataXML(TypeXML i_typeXML = DEFAUT_XML);
        virtual ~CDataXML(void);
    private:
        template<class Archive>
        void serialize(Archive& ar, const unsigned int version)
        {
            ar & BOOST_SERIALIZATION_NVP(m_strNom)
                & BOOST_SERIALIZATION_NVP(m_typeXML);
        }
    public:
        std::string m_strNom;
        TypeXML m_typeXML;
     
        virtual void DataLoad(CDataXML * l_pData)
       {
            m_typeXML = l_pData->m_typeXML;
            m_strNom = l_pData->m_strNom;
        }
    };
     
    //////////////////////////
    /// classe dérivé de CDataXML
    ///////////////////////////
    class SYL_ENGINEXML_EXPORT CTestXML2: public CDataXML
    {
        friend class boost::serialization::access;
    public:
        CTestXML2():CDataXML(),
        m_strParametre("none")
        {}
        ~CTestXML2()
        {}
    private:   
        template<class Archive>
        void save(Archive & ar, const unsigned int version) const
        {
            CDataXML l_object = boost::serialization::base_object<CDataXML>(*this);
            ar & BOOST_SERIALIZATION_NVP(l_object)
               & BOOST_SERIALIZATION_NVP(m_strParametre);
        }
        template<class Archive>
        void load(Archive & ar, const unsigned int version)
        {
            CDataXML l_object = boost::serialization::base_object<CDataXML>(*this);
            ar & BOOST_SERIALIZATION_NVP(l_object)
               & BOOST_SERIALIZATION_NVP(m_strParametre);
            CDataXML::DataLoad(&l_object);
        }
        BOOST_SERIALIZATION_SPLIT_MEMBER()    
    public:
        std::string m_strParametre;
     
     
    };
    ////////////////
    /// classe dérivé de CTestXML2
    /////////////////
    class SYL_ENGINEXML_EXPORT CTestXML2_2: public CTestXML2
    {
        friend class boost::serialization::access;
    public:
        CTestXML2_2():CTestXML2(),
        m_strParametre2_2("none2_2")
        {}
        ~CTestXML2_2()
        {}
    private:   
        template<class Archive>
        void save(Archive & ar, const unsigned int version) const
        {
            CTestXML2 l_test2 = boost::serialization::base_object<CTestXML2>(*this);
            ar & BOOST_SERIALIZATION_NVP(l_test2)
                & BOOST_SERIALIZATION_NVP(m_strParametre2_2);
        }
        template<class Archive>
        void load(Archive & ar, const unsigned int version)
        {
            CTestXML2 l_test2 = boost::serialization::base_object<CTestXML2>(*this);
            ar & BOOST_SERIALIZATION_NVP(l_test2)
                & BOOST_SERIALIZATION_NVP(m_strParametre2_2);
            CDataXML::DataLoad(&l_test2);
            m_strParametre = l_test2.m_strParametre;
        }
        BOOST_SERIALIZATION_SPLIT_MEMBER()        
    public:
        std::string m_strParametre2_2;
     
     
    };
    et maintenant le code de la méthode de serialiation:

    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
     
    #include <boost/archive/xml_oarchive.hpp>
     
    void CChargeurDataXML::Sauvegarder(std::string i_strNom,boost::shared_ptr<CDataXML> i_DataXML)
    {
        std::ofstream ofileXML(i_strNom.c_str());
        try 
        {
            boost::archive::xml_oarchive oTextArchiveXML(ofileXML);
     
    	    // inscription dans les tables Boost
    	    oTextArchiveXML.register_type(static_cast<CTestXML2 *>(NULL));
    	    boost::serialization::void_cast_register(static_cast<CTestXML2 *>(NULL),static_cast<CDataXML *>(NULL)); 
    	    oTextArchiveXML.register_type(static_cast<CTestXML2_2 *>(NULL));
    	    boost::serialization::void_cast_register(static_cast<CTestXML2_2 *>(NULL),static_cast<CTestXML2 *>(NULL)); 
    	    boost::serialization::void_cast_register(static_cast<CTestXML2_2 *>(NULL),static_cast<CDataXML *>(NULL)); 
     
            CDataXML * l_pDataXML = i_DataXML.get();
            oTextArchiveXML << BOOST_SERIALIZATION_NVP(l_pDataXML);    // sérialisation
        }
        catch(boost::archive::archive_exception & e)
        {
            std::cout << e.what();
        }
        ofileXML.close();
    et presque pareille pour desserialiser

    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
     
     
    #include <boost/archive/xml_iarchive.hpp>
     
        std::ifstream ifileXML(i_strNom.c_str());
        try 
        {
            boost::archive::xml_iarchive iTextArchiveXML(ifileXML);
    	    // inscription dans les tables Boost
    	    iTextArchiveXML.register_type(static_cast<CTestXML2 *>(NULL));
    	    boost::serialization::void_cast_register(static_cast<CTestXML2 *>(NULL),static_cast<CDataXML *>(NULL)); 
    	    iTextArchiveXML.register_type(static_cast<CTestXML2_2 *>(NULL));
    	    boost::serialization::void_cast_register(static_cast<CTestXML2_2 *>(NULL),static_cast<CTestXML2 *>(NULL)); 
    	    boost::serialization::void_cast_register(static_cast<CTestXML2_2 *>(NULL),static_cast<CDataXML *>(NULL)); 
     
            CDataXML * l_pData = o_DataXML.get();
            iTextArchiveXML >> BOOST_SERIALIZATION_NVP(l_pData);     // déssérialisation
            o_DataXML = boost::shared_ptr<CDataXML>(l_pData);
        }
        catch(boost::archive::archive_exception & e)
        {
            std::cout << e.what();
        }
        ifileXML.close();
    J'espère que ça aidera quelqu'un ayant les mêmes problème que moi

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    Pour ceux qui sont intéressé par la serialisation XML, j'ai fini une premiere version de mon projet utilisant cette biblioteque.

    Je les invites à regarder ma signature. Il y a les liens vers la section du forum ou je parle de mon projet et le vient vers le téléchargement de la démo ou j'ai joints les sources du module boost XML.

    Sinon j'ai une perte de temps de 32%: 10,5 s avec les infos codées en dur contre 13,9 pour la lecture de ces infos dans mes fichiers XML.

    A votre avis est ce que c'est bien par rapport à d'autre lib XMl comme xerces ou tinyXML?

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

Discussions similaires

  1. Boost.Serialization : attributs XML ?
    Par cob59 dans le forum Boost
    Réponses: 0
    Dernier message: 12/12/2011, 11h57
  2. Réponses: 2
    Dernier message: 04/03/2011, 10h56
  3. boost serialize XML
    Par micou dans le forum Boost
    Réponses: 3
    Dernier message: 05/12/2010, 09h38
  4. Réponses: 2
    Dernier message: 14/11/2009, 02h17
  5. Boost serialize xml et class template
    Par EmlTakeo dans le forum Boost
    Réponses: 1
    Dernier message: 22/08/2008, 09h27

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