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

Langage C++ Discussion :

char* et big-endian


Sujet :

Langage C++

  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    427
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 427
    Par défaut char* et big-endian
    Bonjour,

    quand je crée un char*

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int numBytes = sizeof(int);
    int value = 2024 ;
    char* bytes = (char*)malloc(numBytes);
    memcpy( bytes, &value, numBytes );
    il est dans l'ordre little-endian, peut-on le créer directement en big-endian ?

    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 600
    Par défaut
    Bonjour,

    Peux tu préciser ta question?
    Un pointeur char* c'est un nombre, ça pas de sens de parler d'endianess pour cela.
    Si par contre on s'intéresse à ce qui est pointé, l'endianess aurait un sens, mais ici il s'agit de bytes (=char) qui sont placés les uns après les autres et donc l'endianess n'interviendrait pas.
    A moins que les bytes fassent plusieurs octets, là savoir s'ils sont big-endians ou little-endian est important, est-ce bien la question?

    Si on suit ton exemple, tu te place dans le cas particulier d'un entier. Et si c'était un short, et si c'était un long? Le traitement à faire ne serait pas le même pour changer l'endianess.
    Le seul moyen est de forcer les données à être dans l'ordre où te le souhaite, est de faire que ce code ne dépende pas de l'endianess de ton processeur (qui serait ici little-endian). Je suppose que les char font un octet dans mon exemple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void  write_int( unsigned char* pt, unsigned int x ) {
        for ( size_t i{} ; i < sizeof(int) ; ++i ) {
            pt[i+sizeof(int)-1] = static_cast<unsigned char>( x );   // écriture d'un buffer big-endian
            x >>= 8;
        }
    }

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    427
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 427
    Par défaut
    un "int" occupe 4 octets (4 char)
    j'ai le même problème sur Mac en Objective-C
    je suis en big-endian si j'utilise std::reverse()

  4. #4
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 226
    Par défaut
    l'endianess n'a aucun sens sur 1 octet , donc j'ai du mal à comprendre la question.

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    427
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 427
    Par défaut
    les 4 char retourne -24 7 0 0
    alors que le reverse retourne 0 0 7 -24
    il y a 4 octets ?

  6. #6
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 226
    Par défaut
    ah oui , tu voulais afficher ton int , un simple affichage hexadécimal aurait suffit.
    Donc oui , il faut inverser.

    sur stackoverflow , tu serait tomber sur ce genre de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    uint32_t b0,b1,b2,b3;
    uint32_t res;
     
    b0 = (num & 0x000000ff) << 24u;
    b1 = (num & 0x0000ff00) << 8u;
    b2 = (num & 0x00ff0000) >> 8u;
    b3 = (num & 0xff000000) >> 24u;
     
    res = b0 | b1 | b2 | b3;

  7. #7
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 158
    Billets dans le blog
    4
    Par défaut
    L'endianness dépend de ta machine.
    https://bousk.developpez.com/cours/s...on-bases/#LI-A
    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.

  8. #8
    Membre très actif
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    427
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 427
    Par défaut
    D'après mes tests Windows, Android, iOS, macOS, Ubuntu, Fedora utilisent little-endian.

  9. #9
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 600
    Par défaut
    Citation Envoyé par pol2095 Voir le message
    D'après mes tests Windows, Android, iOS, macOS, Ubuntu, Fedora utilisent little-endian.
    Comme écrit plus haut, ça n'est pas le système d'exploitation qui décide, c'est le processeur. Par exemple, les Intel sont presque tous little-endian, les PowerPC étaient big mais sont little depuis la V10, les ARM sont little ou big.

    Sur un code écrit correctement, c'est totalement transparent.

    Quand on doit sérialiser les données, c'est le protocole qui indique quel format utiliser. Là c'est souvent poids fort en tête, ce qui correspondrait au big-endian.

  10. #10
    Membre très actif
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    427
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 427
    Par défaut
    je teste si le système est little ou big endian, en fonction j'utilise un reverse ou pas pour le int.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 401
    Par défaut
    Franchement t'as plus vite fait de faire un code qui écrit directement octet par octet sans passer par memcpy().
    Ce sera plus portable et tu n'auras même pas besoin de faire un test!

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void write_be32(std::vector<char> &sortie, unsigned int entier)
    {
    	auto b0 = static_cast<unsigned char>(entier);
    	auto b1 = static_cast<unsigned char>(entier >> 8);
    	auto b2 = static_cast<unsigned char>(entier >> 16);
    	auto b3 = static_cast<unsigned char>(entier >> 24);
    	//Et pour la version qui sérialise toujours en little-endian, il suffit juste d'inverser l'ordre des 4 lignes qui suivent
    	sortie.push_back(b3);
    	sortie.push_back(b2);
    	sortie.push_back(b1);
    	sortie.push_back(b0);
    }
     
    void write_be32(std::vector<char> &sortie, int entier) { write_be32(sortie, static_cast<unsigned int>(entier)); }

    Et si tu tiens vraiment à utiliser un pointeur nu:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void write_be32(char* &sortie, unsigned int entier)
    {
    	auto b0 = static_cast<unsigned char>(entier);
    	auto b1 = static_cast<unsigned char>(entier >> 8);
    	auto b2 = static_cast<unsigned char>(entier >> 16);
    	auto b3 = static_cast<unsigned char>(entier >> 24);
    	//Et pour la version qui sérialise toujours en little-endian, il suffit juste d'inverser l'ordre des 4 lignes qui suivent
    	*(sortie++) = b3;
    	*(sortie++) = b2;
    	*(sortie++) = b1;
    	*(sortie++) = b0;
    }
     
    void write_be32(char* &sortie, int entier) { write_be32(sortie, static_cast<unsigned int>(entier)); }
    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.

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

Discussions similaires

  1. Conversion little vers big endian
    Par kris1980 dans le forum x86 32-bits / 64-bits
    Réponses: 8
    Dernier message: 16/08/2007, 14h42
  2. Pb avec "BIG ENDIAN"
    Par pdgnr dans le forum Delphi
    Réponses: 2
    Dernier message: 04/09/2006, 10h37
  3. Big endian et Little endian?
    Par moon93 dans le forum C
    Réponses: 4
    Dernier message: 07/05/2006, 23h48
  4. Cast et little/big endian
    Par progfou dans le forum C
    Réponses: 8
    Dernier message: 29/03/2006, 19h54
  5. Comment écrire en big endian dans un fichier ?
    Par j3d dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 24/07/2005, 22h50

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