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++/CLI Discussion :

Petit problème de serialisation


Sujet :

C++/CLI

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Points : 64
    Points
    64
    Par défaut Petit problème de serialisation
    Bonjour, dans une classe managée j'ai d'autres instances de classes managées. Pour sérialiser et désérialiser ma classe principale, j'appelle directement un Runtime::Serialization::Formatters::Binary::BinaryFormatter.
    Je rajoute l'attribut [Serializable] de l'assembleur au début de chaque déclaration de classe.

    Le problème c'est que lorsque je désérialise l'instance de la classe principale à partir d'un fichier je ne récupère que les variables de l'instance tandis que les instances de classes managées prennent leur valeur par défaut. Est-ce qu'il serait possible de faire le plus simple possible pour contourner ce problème. Est-ce que par exemple il est nécessaire d'utiliser l'interface ISerializable ?

    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
     
    [Serializable]
    public ref class A
    {
    public:
          // ...
    };
     
    [Serializable]
    public ref class B
    {
    public:
          // ...
          A ^pA;
    };
     
    int main(...)
    {
         Runtime::Serialization::Formatters::Binary::BinaryFormatter ^bf;
         bf = gcnew Runtime::Serialization::Formatters::Binary::BinaryFormatter;
         B ^instance;
         String ^filename = "...";
     
         // Serialisation
         IO::StreamWriter ^writer = gcnew IO::StreamWriter(filename);
         bf->Serialize(writer->BaseStream, instance);
         writer->Close();
     
         // Deserialisation
         IO::StreamReader ^reader = gcnew IO::StreamReader(filename);
         instance = (B^) (bf->Deserialize(reader->BaseStream));
         reader->Close();
     
         // A n'est pas initialisé à partir des paramètres déclarés à la sérialisation
         //...
    }

  2. #2
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    cela devrait, c'est fait pour, à partir du moment où tes propriétés à sérialiser sont publiques

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    La présence d'un constructeur désérialisant n'est-elle pas obligatoire pour la sérialisation normale ?
    Ou est-elle seulement nécessaire si on implémente ISerializable ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Points : 64
    Points
    64
    Par défaut
    J'ai oublié un détail !
    En prenant l'exemple ci-dessus la classe A est dans une dll et la classe B dans une autre.
    J'appelle la sérialisation dans mon application.
    C'est donc probable que j'utilise l'interface ISerializable non?

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Points : 64
    Points
    64
    Par défaut
    La présence d'un constructeur désérialisant n'est-elle pas obligatoire pour la sérialisation normale ?
    Ou est-elle seulement nécessaire si on implémente ISerializable ?
    La question que je pose est alors : "Comment est ce que je crée un constructeur de désérialisation ?".
    (c'est la première fois que j'utilise la sérialisation avant j'utilisais IO pour enregistrer mes instances de classe )

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Dans la doc de ISerializable, ils décrivent le constructeur désérialisant: Il prend deux paramètres particuliers, qui contiennent les données sérialisées...

    PS: À ma connaissance, on n'utilise pas ISerializable, on l'implémente.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Points : 64
    Points
    64
    Par défaut
    Bon je propose le prototype de code suivant qui ne marche pas mais que vous pourrez sans doute corriger.
    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
     
    // Dans une dll 1
    [Serializable]
    public ref class A sealed : public ISerializable
    {
    public:
          // ...
          virtual void GetObjectData(SerializationInfo ^info, StreamingContext context)
          {
                // On ajoute les valeurs des instances A à sérialiser ici
                info->AddValue("value", values);
          }
    };
     
    // Dans une Dll 2
    [Serializable]
    public ref class B sealed : public ISerializationSurrogate
    {
    public:
          // ...
          A ^pA;
     
          // Normalement appelée lors de la sérialisation
          virtual void GetObjectData(System::Object ^obj, SerializationInfo ^info, StreamingContext context)
          {
                B ^b = (B^) obj;
                info->AddValue("B::pA", b->pA, A::typeid);
          }
          // Normalement appelée lors de la désérialisation
          virtual System::Object ^SetObjectData(System::Object ^obj, SerializationInfo ^info, StreamingContext context, ISurrogateSelector ^selector)
          {
                B ^b = (B^) obj;
                b->pA = (A^) info->GetValue("B::pA");
                return obj;
          }
     
    };
     
    generic <typename T>
    void fctSerialize(String ^filename, T instance)
    {
    	IO::StreamWriter ^writer = gcnew IO::StreamWriter(filename);
    	Runtime::Serialization::Formatters::Binary::BinaryFormatter ^bf = gcnew Runtime::Serialization::Formatters::Binary::BinaryFormatter;
    	bf->Serialize(writer->BaseStream, instance);
    	writer->Close();
    }
     
    generic <typename T>
    T fctDeserialize(String ^filename, T instance)
    {
    	IO::StreamReader ^reader = gcnew IO::StreamReader(filename);
    	Runtime::Serialization::Formatters::Binary::BinaryFormatter ^bf = gcnew Runtime::Serialization::Formatters::Binary::BinaryFormatter;
    	instance = static_cast <T> (bf->Deserialize(reader->BaseStream));
    	reader->Close();
    	return instance;
    }
     
    // Dans mon appli
    int main(...)
    {
        B ^b; // avec initialisation de l'instance pA
        // ...
        fctSerialize("filename", b);
        // on redémarre l'appli et on désérialise pour le test
        b = fctDeserialize("filename", b);
    }

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    À ma connaissance, il n'y a pas de méthode SetObjectData() : Il y a le constructeur désérialisant à la place.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2006
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2006
    Messages : 94
    Points : 64
    Points
    64
    Par défaut
    En fait, je viens de découvrir la question principale du problème :
    si on fait appel à des instances classes définies dans une dll implémentées dans une classe définie dans le code de l'application, est-ce que la sérialisation peut s'effectuer sans que ces instances soient sérialisées sans que leurs valeurs soient corrompues ?

    J'ai essayé de faire une sérialisation classique avec toutes les classes définies avec l'application et tout est sérialisé et désérialisé correctement sauf les instances de classes provenant de dlls...

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

Discussions similaires

  1. un petit problème d'algo
    Par supertramp dans le forum Algorithmes et structures de données
    Réponses: 22
    Dernier message: 12/10/2004, 20h13
  2. Petit problème de décimales !
    Par ridan dans le forum Langage SQL
    Réponses: 5
    Dernier message: 11/09/2004, 21h24
  3. Réponses: 17
    Dernier message: 13/07/2004, 20h37
  4. petit problème premier plan, arrière plan
    Par gros bob dans le forum OpenGL
    Réponses: 4
    Dernier message: 19/04/2004, 12h00
  5. [jointure] Petit problème sur le type de jointure...
    Par SteelBox dans le forum Langage SQL
    Réponses: 13
    Dernier message: 13/02/2004, 18h55

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