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 :

Le problème de sauvegarde de donnée binaire en C++ et la portabilité


Sujet :

C++

  1. #41
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    D'où le point que je voulais soulever: Ces fonctions sont inappropriées pour toute autre chose, comme un format de sauvegarde où l'endianness est variable (et si elle est fixe, pas besoin de l'indiquer dans la sauvegarde).

    D'un autre côté, je ne dis pas qu'un format à endianness variable est une mauvaise idée: Bien fait, c'est le plus performant pour communiquer entre deux machines ayant la même endianness, quelle qu'elle soit.
    Rien n'est indiquée dans sa sauvegarde actuelle, et l'endianness n'est pas variable en utilisant les méthodes ntoh*. La sauvegarde sera toujours en big-endian. Le but c'est bien de fixer l'écriture et lecture de la sauvegarde, à commencer par son format.
    Tu peux ballader tes sauvegardes entre machines, quelle que soit leur endianness, little, bid, mid, tu pourras la lire, ces fonctions te remettront tes données dans l'ordre utile à ta machine. A la simple lecture du code c'est exactement ce que semble faire sa fonction actuelle, en inversant l'ordre en little-endian. Il écrit tout en big-endian..
    Sinon il n'y a aucun besoin de faire quoi que ce soit, juste écrire les buffer tel quel et hop, sans se soucier de l'endianness à aucun moment. Et seule une machine avec le même endianness saura relire.
    Enfin tu pourras les relire avec une autre machine, mais t'auras des valeurs farfelues pour la plupart des cas.

    Donc bon tu fais ce que tu veux, je t'informe juste la bonne façon de faire avec des méthodes éprouvées depuis des années et des millions de fois par jour.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  2. #42
    Membre habitué
    Homme Profil pro
    sans activité
    Inscrit en
    Janvier 2016
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : sans activité

    Informations forums :
    Inscription : Janvier 2016
    Messages : 76
    Points : 136
    Points
    136
    Par défaut
    Bousk, reste le problème qu'il faut des bibliothèques propre au système : les include sont différents suivant les systèmes, je suppose donc que les bibliothèques aussi, après je peux me tromper, je ne suis qu'un noob mais question portabilité c'est discutable.
    Les bibliothèques standards cpp me semble plus à propo.

    Dans le code que j'ai donné, effectivement, j'ai pris le partis d'ecricre mes sauvegarde en big endian car mon systeme est en little. Cela avait plus une valeur de teste qu'autre chose, j'ai prévu une fonction permettant de choisir.

    Sinon, il n'y a effectivement pas de format pour mes sauvegardes propre à la classe et c'est normal car les formats seront spécifiés dans d'autres classes qui utiliseront celle-ci.

    Par contre, les méthodes ntoh & co ne sont toujours valable, à priori d’après la doc que j'ai pu trouvé, que pour des uint16_t et uint32_t ce qui n'est pas le cas de ma classe.

  3. #43
    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
    Le problème, c'est que ton infrastructure n'est pas "intelligente", elle ne fait que prendre des données qu'on lui donne déjà contigües et les écrire, sans se soucier réellement de leur type.

    Une infrastructure de sérialisation "intelligente" sait sur quels types de données elle travaille: Elle a accès à une description des données, que celle-ci soit hard-codée dans le code (spécialisations de fonctions template, etc.) ou quelque chose de plus dynamique (et bcp plus dûr, mais pouvant potentiellement être également sauvegardée dans le fichier, faisant des formats "auto-décrits"). Et c'est dans ce genre de cas que l'infrastructure de sérialisation, sachant sur quels types elle travaille, s'assure de la compatibilité avec un format binaire standardisé (et donc, de l'endianness des données).

    PS: htonl() et compagnie sont faciles à implémenter, au passage:
    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
    uint32_t htonl(uint32_t hostValue)
    {
    	uint8_t buf[4];
    	buf[0] = (uint8_t)(hostValue >> 24);
    	buf[1] = (uint8_t)(hostValue >> 16);
    	buf[2] = (uint8_t)(hostValue >>  8);
    	buf[3] = (uint8_t)(hostValue);
    	return * reinterpret_cast< uint32_t const* >(buf);
    }
     
    uint32_t ntonh(uint32_t netValue)
    {
    	uint8_t buf[4];
    	* reinterpret_cast< uint32_t * >(buf) = netValue;
    	return ((uint32_t)buf[0]) << 24
    		| ((uint32_t)buf[1]) << 16
    		| ((uint32_t)buf[2]) <<  8
    		| ((uint32_t)buf[3])
    		;
    }
    Ceci marche quelle que soit l'endianness de la machine.
    Edit: Ah, mais il pourrait y avoir des problèmes au niveau des contraintes d'alignement, donc il faudrait plutôt remplacer le cast par une union.
    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. #44
    Membre habitué
    Homme Profil pro
    sans activité
    Inscrit en
    Janvier 2016
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : sans activité

    Informations forums :
    Inscription : Janvier 2016
    Messages : 76
    Points : 136
    Points
    136
    Par défaut
    Je ne suis pas sûr de comprendre qui parle à qui, mais bref passons...

    Médinoc, si je te comprends bien (ce qui n'est pas sûr, je vous rappelle que je débute en C++), quand tu parle se sérialisation intelligente, de formats "auto-décrits" pouvant potentiellement être écris dans le fichier, tu parles, grosso modo, de système de fichier, genre avec une table d'indexation des données et de leurs types... (toujours dans l'optique où je comprends ou presque de quoi tu me parles, si c'était bien à moi que tu parlais.)

    Pour la spécialisation des templates, j'ai trouvé des trucs intéressants dans <type_traits> mais les retours obtenus ne correspondais pas à ceux que j'ai pu lire dans la doc donc j'ai laissé ça de côté pour l'instant.

  5. #45
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Tout ça pour réinventer une roue carrée, des framework de sérialisation efficaces et conviviaux à l'utilisation, il y en a plein.
    Si c'est pour la pédagogie, commencez par apprendre comment marche un framework de sérialisation et APRES vous essayez d'implémenter votre roue carrée.
    tu parles, grosso modo, de système de fichier, genre avec une table d'indexation des données et de leurs types
    Non.
    Il parle vraisemblablement de tout ce qui est fait dans les framework de sérialisation, on en revient toujours au même.=> apprendre comment marche un framework de sérialisation.

  6. #46
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par rnr72 Voir le message
    Bousk, reste le problème qu'il faut des bibliothèques propre au système : les include sont différents suivant les systèmes, je suppose donc que les bibliothèques aussi, après je peux me tromper, je ne suis qu'un noob mais question portabilité c'est discutable.
    Et bien si tu veux discuter de et remettre en cause la présence d'une API socket sur toutes les plateformes existantes, libre à toi, mais je te laisserai à ton monologue.
    Sérieusement, vouloir prendre en compte l'unique hypothétique cas particulier, si tenté qu'il existe ? Et encore faut-il que tu déployes ton application dessus.

    Ce dont parle médinoc il me semble serait un header dans la sauvegarde qui indique son format. Voire un mini-header pour chaque donnée pour indiquer de quelle type il s'agit. Comme le BSON par exemple que j'ai découvert dans une récente discussion.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #47
    Membre habitué
    Homme Profil pro
    sans activité
    Inscrit en
    Janvier 2016
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : sans activité

    Informations forums :
    Inscription : Janvier 2016
    Messages : 76
    Points : 136
    Points
    136
    Par défaut
    bacelar, je vais cherché à comprendre comment fonctionnent ces
    framework de sérialisation efficaces et conviviaux à l'utilisation
    , puisque il y en a plein, je ne devrai pas avoir de mal à en trouvé. Il aurai était plus constructif pour un débutant tel que moi de m'orienter vers vos choix de
    framework de sérialisation efficaces et conviviaux à l'utilisation
    plutôt que de prétendre je cherche à réinventé la roue carrée. Me dire ceci comme vous le faites, se n'est pas vraiment m'aider.

    Bousk, je n'ai jamais douter de l'utilité d'API socket même s'il me semble pourtant de celle de Windows et de Linux sont différentes. Par contre dans le cadre du développement d'un programme qui n'a pas vocation à utiliser les réseaux, je remet en question la nécessité de leurs présence et si cette remise en question fait de mes questionnements un monologue et bien tant pis.

    Ce dont parle médinoc il me semble serait un header dans la sauvegarde qui indique son format. Voire un mini-header pour chaque donnée pour indiquer de quelle type il s'agit. Comme le BSON par exemple que j'ai découvert dans une récente discussion.
    Je me suis certainement mal exprimé, je ne connais pas tout le jargon, mais oui c'est ce que j'avais cru comprendre, dit comme vous l'avez fait c'est encore plus clair, merci.

  8. #48
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Il aurai était plus constructif pour un débutant tel que moi de m'orienter vers vos choix de
    Boost.serialize par exemple :http://www.boost.org/doc/libs/1_60_0...alization/doc/
    Entre plein d'autres.

  9. #49
    Membre habitué
    Homme Profil pro
    sans activité
    Inscrit en
    Janvier 2016
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : sans activité

    Informations forums :
    Inscription : Janvier 2016
    Messages : 76
    Points : 136
    Points
    136
    Par défaut
    bacelar, bonjour et merci.

    J'ai effectivement cherché à analyser les sources de boost.serialize et boost.archives mais pour être franc je me suis cassé les dents dessus.

    Mon niveau en cpp et en programmation en général ne me permet apparemment pas de comprendre ce code dans son intégralité, il faut constamment sauter d'un fichier à un autre et je m'y perd mais ne renonce pas.

    Par contre, je maintient que pour moi, il est plus formateur de trouver les réponses par moi-même que de prendre les solutions des autres mais je ne les rejette pas pour autant, c'est effectivement une bonne source d'inspiration. Et je pense également que je serai plus à même de comprendre les "codes complexes" comme ceux de boost lorsque j'aurai moi-même écris de grande quantité de "codes complexes".

    Je pense que c'est en développant que l'on devient développeur, même si il est vrai qu'il est bon de s'inspirer des "meilleurs".

    Cordialement RNR72.

  10. #50
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    boost n’est pas toujours ce qu’il y a de plus facile à prendre en main, surtout pour un débutant en C++.

    Tu peux regarder du côté du framework Qt qui fournit des méthodes de sérialisation (entre autres choses), peut-être plus simples à utiliser que boost.

    L’autre point, c’est que puisque tu débutes, il faut te fixer un objectif assez simple. Donc fixer l’endianness dans ton format, par exemple, plutôt que de faire une endianness variable spécifiée en début de fichier (ce qui peut avoir du sens dans certains contextes, comme le soulignait Médinoc, mais rajoute de la complexité).

  11. #51
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par rnr72 Voir le message
    bacelar, bonjour et merci.

    J'ai effectivement cherché à analyser les sources de boost.serialize et boost.archives mais pour être franc je me suis cassé les dents dessus.

    Mon niveau en cpp et en programmation en général ne me permet apparemment pas de comprendre ce code dans son intégralité, il faut constamment sauter d'un fichier à un autre et je m'y perd mais ne renonce pas.
    C'est sans doute bien de là que vient le problème :

    Tu donnes l'impression de vouloir savoir courir (implémenter ton propre système de sérialisation) alors que tu ne sais pas encore marcher (comprendre du code d'un niveau "correct").
    Par contre, je maintient que pour moi, il est plus formateur de trouver les réponses par moi-même que de prendre les solutions des autres mais je ne les rejette pas pour autant, c'est effectivement une bonne source d'inspiration. Et je pense également que je serai plus à même de comprendre les "codes complexes" comme ceux de boost lorsque j'aurai moi-même écris de grande quantité de "codes complexes".
    Ce sera -- sans aucun doute -- très formateur... quand tu auras suffisamment d'expérience en C++ pour comprendre les différents aspects mis en oeuvre... Et ce n'est visiblement pas pour maintenant

    Le pire de l'histoire, c'est que, une fois que tu auras assez d'expérience pour comprendre le code qui t'es fourni avec boost, tu vas peut-être essayer de créer un système "à ta mode" (pour l'entrainement, bien sur!!!) avant... de décider au final de quand même utiliser boost serialize, car tu te rendra compte que la qualité est loin d'être au rendez vous avec ta roue carrée

    Mais bon, nous ne sommes que de vieux cons qui avons fait les mêmes erreurs avant toi et qui essayons de te faire profiter de notre expérience... Tu en fais au final ce que tu veux, nous, on a déjà compris
    Je pense que c'est en développant que l'on devient développeur, même si il est vrai qu'il est bon de s'inspirer des "meilleurs".
    Bien sur que c'est en développant qu'on devient développeurs, mais c'est en choisissant les batailles que l'on mène que l'on devient général sans s'être fait bêtement tuer par un ennemi contre lequel on n'avait aucune chance

    Tu veux développer je n'ai qu'un conseil à te donner : développe! Et des choses de plus en plus complexes! Mais ne passes pas d'un coup d'un projet dont le niveau de complexité se trouve à 1 à un projet dont le niveau de complexité se trouve aux alentours de 10! Il y aura un écart beaucoup trop grand entre ce que tes connaissances et ton instincts te permettent de faire et ce que le projet te demande de faire.

    N'importe quel imbécile peut décider de se lancer dans l’ascension de l'Everest, mais seules les personnes correctement entrainées ont une chance d'y arriver sans y perdre la vie ou un pied

    Une fois que tu as résolu un problème de "niveau 1", passe à un problème de "niveau 2" et résout autant de problèmes de "niveau 2" que nécessaire pour en arriver à un point où tu arrives à les résoudre... pour ainsi dire sans y penser. Et ce n'est qu'une fois que tu arrives à ce point que tu peux envisager de passer à "l'étape supérieure", en sachant qu'il y aura forcément "de nouvelles choses à expérimenter et à apprendre".
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #52
    Membre habitué
    Homme Profil pro
    sans activité
    Inscrit en
    Janvier 2016
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : sans activité

    Informations forums :
    Inscription : Janvier 2016
    Messages : 76
    Points : 136
    Points
    136
    Par défaut
    Bonjour,

    white_tentacle,
    merci pour ton message, je regarderai la partie sérialisation du framework QT mais j'ai bien peur que les sources soit aussi cryptique que celle de boost car même si la sérialisation de QT est plus facile à utiliser ce n'est pas pour cela que son code est plus simple.

    L'endianness de mon fichier est bien variable aujourd'hui, j'ai pris le parti qu'elle serai celle du système lors de la création du fichier. J'en ai même fais plus, j'ai également créé une table d'allocation qui me permet de retrouver mes données en fonction de leur nom et leur type ce qui me permettra de pouvoir les lire dans l'ordre que je veux et de n’écrire que les données qui ont changées sans me préoccuper des autres.

    koala01,
    effectivement je dois bien reconnaitre que cette idée de créer ma propre classe de sérialisation était pour moi de l'ordre de l'Everest mais comme je ne suis pas totalement fou, je suis redescendu avant les gros problèmes (je ne suis pas encore mort et j'ai encore tout mes membres ). Certes j'ai envie de courir alors que je ne sais pas marcher mais dans tous les cas les chutes font parties de l'apprentissage.
    Je ne sais pas si je finirai un jour général mais j'ai vite compris que en l'état cette bataille ne serai pas gagnable mais la guerre n'est pas finit pour autant. J'envisage le K2!

    Toutes métaphores alpino-bellicistes misent à part, merci pour ces conseils. (Je te rassure mon vieux, vu d'ici, tes "conneries" ont un goût de sagesse)

Discussions similaires

  1. Réponses: 2
    Dernier message: 26/05/2011, 22h06
  2. [1.x] Problème de sauvegarde des données avec embed form
    Par Vicrabb dans le forum Symfony
    Réponses: 2
    Dernier message: 24/11/2010, 12h11
  3. [MySQL] problème de sauvegarde de données dans la base MySQL
    Par hassen07 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 27/05/2010, 21h58
  4. Réponses: 2
    Dernier message: 19/09/2007, 21h00
  5. Problème pour sauvegarder mes données
    Par ploup dans le forum Windows Forms
    Réponses: 5
    Dernier message: 04/05/2007, 14h17

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