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 :

Déterminer l'endianness du système?


Sujet :

C

  1. #21
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Ou alors avec une fonction de copie de zone mémoire.
    Mais le principe est il correct : on n'est pas obligé de ranger les byte?

  2. #22
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par seriousme
    Ou alors avec une fonction de copie de zone mémoire.
    Mais le principe est il correct : on n'est pas obligé de ranger les byte?
    Si la représentation mémoire est exactement celle du réseau et qu'il n'y a pas de problèmes d'alignement, ça ira.

    Ce n'est pas trivial et ce n'est pas portable. J'ai proposé une méthode universelle. Est-elle vraiment couteuse ? Peut être... il faut faire des mesures...

  3. #23
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    la représentation mémoire
    L'endianness ou ça recouvre autre chose?
    ce n'est pas portable
    Si l'endianness du système est bien vérifiée et que la norme de transmission est respectée ça devrait être portable.

  4. #24
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par seriousme
    L'endianness ou ça recouvre autre chose?
    La largeur de la donnée, par exemple, son alignement...
    Si l'endianness du système est bien vérifiée et que la norme de transmission est respectée ça devrait être portable.
    Du 'portable' à coups de 'si', c'est plus du portable...

    Enfin, si ça t'amuse...

  5. #25
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    seriousme : C'est à cela que servent htons/htonl...

    Sur une architecture Big-Endian, il arrive qu'on trouve directement des macros #define htons(x) (x), donc aucune perte de performance...
    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.

  6. #26
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 3
    Par défaut
    Bonjour,

    voila pour un projet je doit faire une fonction qui recois un int et le retranscrit dans un fichier en une chaine de caractere. Seulement, et pour une question de portabilite il me faut connaitre l'endian de la machine sur laquelle je suis (sinon je risque une foi sur 2 de retranscrire mon entier a l'envers).

    J'ai par consequent fait quelques recherches avant de tomber sur ce topic et sur ce qui suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int x = 1;
    	if(*(char *) & x == 1)
    seulement je ne suis pas sur de bien comprendre ce if, et etant hors de question que je me serve d'un bout de code que je ne comprend pas je viens a vous pour vous demander quelques precisions:

    - nous avons donc un masque binaire, mais je m'etonne qu'il ne soit pas fait bit par bit, et surtout que l'on compare un int (sur 4 octets) a un char (sur 1 octet).
    - a quoi correspond la premiere etoile juste apres le if ?
    - et d'ou vient donc ce char ?

    Merci de bien vouloir repondre a tout ces questions certainement tres triviales pour vous mais qui pourraient m'etre d'une grande aide.

  7. #27
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par jeroim
    voila pour un projet je doit faire une fonction qui recois un int et le retranscrit dans un fichier en une chaine de caractere.
    sprintf(), fprintf()...
    Seulement, et pour une question de portabilite il me faut connaitre l'endian de la machine sur laquelle je suis (sinon je risque une foi sur 2 de retranscrire mon entier a l'envers).
    Pas du tout. Quand c'est converti en texte, c'est auto-démerdant (au charset près, mais ASCII couvre 99% des cas). Et même si c'était en binaire (tableau de bytes), du moment que le format du fichier (ou du flux) est spécifié (généralement 'réseau', c'est à dire MSB en tête), on sait écrire du code portable indépendant de l'endiannes, à coup de tableau de unsigned char et d'opérateurs binaires &, |, >>, << etc.

    Donc, faux problème.

  8. #28
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    il y a un autre moyen dynamique :

    Là c'est appliqué à des ports, mais ça indique directement little ou big endian...

    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
    typedef union
    {
       int i ;
       char carac[4] ;
    }TestStruct ;
    
      test.i = 123 ;
      if ( test.carac[0] == '{' ){
        /* network byte order.
         * We change to host byte order
         * and return the value. 
         */
        return (ntohs(isp->s_port)) ;
      }
      else{    /* host byte order.
         * We simply returns the value. 
         */
        return (isp->s_port) ;
       
      }
    ça m'a été très utile pour faire communiquer des machines Unix(HPUX, Silicon Graphics Mips) et des Linux... car :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      * On Linux machine getservbyname
      * returns the port in network order while on unix 
      * machine it is not clear. Therefore we performe a test to check
      * the byte order for the local machine.
      * if the machine is is network byte order we use the
      * function ntohs (network to host) the change it.

  9. #29
    Membre émérite

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Par défaut
    Citation Envoyé par souviron34
    il y a un autre moyen dynamique : [...]
    Un autre ? A part la valeur de "i", quelle différence fondamentale avec ce que j'avais donné ici ?

  10. #30
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 3
    Par défaut
    Tout d'abbord merci pour vos reponses,

    Citation Envoyé par Emmanuel Delahaye
    sprintf(), fprintf()...
    en fait je ne peu me servir que de write();
    voici ce que j'ai pour le moment, et on m'a genttilment indique que ca ne marcherai pas :
    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
     
     
    /* les valeurs dans l'int sont en hexadecimal, */
    /* les calculs sont donc fait dans cette base */
     
    void	put_to_file(t_list_hexa *h, char *name)
    {
      char	*str;
      int	fd;
     
        /* ouverture du fichier et application des droits */
      fd = open(name, O_CREAT | O_RDWR | O_TRUNC, 0760);
      if (fd < 0) /* verification de la valeur de retour de open */
        {
          write(1, "Cannot open file\n", 18);
          exit(-1);
        }
      while (h != NULL) /* les donnees sont dans l'int hex dans cette liste chainee */
        {
          str = xmalloc(sizeof(char) * 2);
          str = put_to_char(h, str);
          write(fd, str, 2);
          free(str);
          h = h->next; /* incrementation de la liste chainee */
        }
      close(fd);
    }
     
    /* on ecrit dans le char * les caracteres un par un */
    char	*put_to_char(t_list_hexa *h, char *str)
    {
      if (h->hex < 10)
        {
          str[0] = '0';
          str[1] = put_to_char_sub(h->hex, str[1]);
        }
      else
        {
          str[1] = put_to_char_sub(h->hex % 10, str[1]);
          str[0] = put_to_char_sub(h->hex / 10, str[0]);
        }
      return (str);
    }
     
    char	put_to_char_sub(int hex, char str)
    {
      if (hex < a)
        str = hex + 30; /* on ajoute ce qu'il faut pour arriver */
      else
        str = hex + 57; /* a la valeur ascii du caractere hexa */
      return (str);
    }
    voila, moi ca me semblait tres simple comme vous pouvez le voir et j'ai eu un tres beau : "oui mais tu ne gere pas les differents endian comme ca" ...

  11. #31
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    ok désolé j'avais mal lu.. à cause du gros free en rouge !!

  12. #32
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 3
    Par défaut
    Et bien j'ai finalement compris ce fameux if qui permet de recuperer l'endian de la machine (une bonne nuit de sommeil de temps a autres fait du bien aux neurones ^^)

    je vais desormais regarder pour m'en servir a bon escient, merci encore, bonne continuation.

  13. #33
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par jeroim
    en fait je ne peu me servir que de write();
    Alors il faut cesser de parler de portabilité.
    voici ce que j'ai pour le moment, et on m'a genttilment indique que ca ne marcherai pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /* les valeurs dans l'int sont en hexadecimal, */
    Ceci n'a aucun sens. Dans une variable il n'y a que des 0 ou des 1. C'est du binaire. Point.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /* les calculs sont donc fait dans cette base */
    What ? Quels calculs ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          str = xmalloc(sizeof(char) * 2);
    Ca sert à quoi d'allouer dynamiquement une tableau de taille fixe ? A m'énerver ? Accessoirement, sizeof(char) vaut 1. Toujours. (Normal, c'est l'unité de compte)

    "Combien y'a d'euros dans un euro ? Ben un, pourquoi ? "

    Alors dans un char, y'a un char. Voilà. Logique basique...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          str = put_to_char(h, str);
    Va falloir qu'on m'explique à quoi sert cette fonction et surtout pourquoi elle modifie str...

    Ah ça vient ...
    /* on ecrit dans le char * les caracteres un par un */
    Ouch ! Tout ça pour faire une conversion num/texte en hexadécimal ? Tu devrais réfléchir au fait que les données sont codées en binaire et qu'il suffit de les traiter par groupe de 4 bits pour déterminer quelle valeur comprise entre 0 et F (0-15) on a. C'est très simple, et il n'y a aucun problème de portabilité dû à l'endianess.

    Je propose :

    int num2hex(char *s, int width, unsigned data);

    qui s'utilise comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
       char chaine [10]; /* a l'aise */
       unsigned donnee = 128; /* 0-255 soit 00 a FF  d'ou une largeur de 2 */
       int largeur = 2;
       int err = num2hex (chaine, largeur, donnee);
     
       if (!err)
       {
           /* OK */
    a toi de coder la fonction. Je suggère que la chaine construite soit valide, c'est à dire terminée par un 0, ça peut aider au debug (printf)

    Avec 128, on doit obtenir "80".

  14. #34
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par jeroim
    Et bien j'ai finalement compris ce fameux if qui permet de recuperer l'endian de la machine
    Il n'y a pas ce problème avec ce que tu veux faire. Tu perds ton temps...

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Déterminer les coordonnées 3D d'un système stéréo
    Par wheelskad dans le forum OpenCV
    Réponses: 25
    Dernier message: 13/05/2012, 21h56
  2. Déterminer version 32/64 bits du système d'exploitation
    Par Maxiglider dans le forum Langage
    Réponses: 10
    Dernier message: 14/02/2011, 15h11
  3. Déterminer l'emplacement des dossiers systèmes
    Par soso78 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 04/01/2008, 10h33
  4. Réponses: 2
    Dernier message: 16/05/2007, 19h26
  5. [Système] Déterminer l'état d'un process
    Par 501darts dans le forum Langage
    Réponses: 1
    Dernier message: 30/01/2007, 18h59

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