La conversion d'Endianess sur un champ de bits de la structure
J'ai besoin de convertir un peu de champ de structure de little-endian à grand-endia architecture.
Quelle est la meilleure façon de le faire, comme il y aura des problèmes dans les limites d'octets, si j'ai simplement permuter les éléments de la structure.
Ex Structure:
struct {
unsigned int b1:1;
unsigned int b2:8;
unsigned int b3:7;
unsigned int b4:8;
unsigned int b5:7;
unsigned int b6:1;
};
Votre question était assez pour répondre à ma question au sujet de quelque chose de séparé - merci! 🙂
OriginalL'auteur foo | 2009-04-07
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser un entier de 32 bits, et d'extraire des informations de l'aide et de l' - et bitshift opérateurs. Avec cela en place, vous pouvez simplement utiliser htonl (hôte-réseau, long). Ordre des octets de réseau est en big endian.
Ce ne sera pas aussi élégant comme un peu de champ, mais au moins vous saurez ce que vous avez et n'aurez pas à vous soucier de le compilateur rembourrage de vos structures.
Oui vous avez raison, si le epatel la méthode donnée ci-dessous fonctionne aussi, j'ai juste besoin de voir où ça ne marchera pas 🙂
La méthode donnée par epatel est aussi très courants (et je upvoted aussi!). Mais il peut être difficile lorsque les champs de bits de chevauchement d'une frontière d'octet.
Gardez à l'esprit que c'est seulement sur windows. Avec cela, vous devez inclure tous les winsock libs (ws2_32.lib), ce qui peut ajouter de façon déraisonnable montant des frais généraux de votre projet.
OriginalL'auteur falstro
Processeur endianness est sans rapport avec champ de bits de commande. Il est tout à fait possible d'avoir deux compilateurs sur la même utilisation de l'ordinateur en face de la commande pour bitfields. Donc, étant donné ce:
Sauf si vous arrive d'avoir une documentation détaillée, la seule façon de savoir si cela va imprimer 01 ou 80 est de l'essayer.
OriginalL'auteur Tim
Dans un projet de portage de code de MIPS pour Linux/x86 nous avons fait comme ça.
Les macros
__ONE_ENDIANESS__
et__OTHER_ENDIANESS__
a été approprié pour le compilateur nous avons utilisé de sorte que vous pourriez avoir besoin de regarder dans ce qui est approprié pour vous...Pas? Je pense que si sizeof(int) il a bien fonctionné pour nous...
ah 😉 vu aujourd'hui...je viens de l'édition sans regarder...de fixation!
sûrement sizeof (int) est de 4, ou quelque petite valeur comme ça? L'unité de sizeof est chars, donc, pour un int 32-bits sur une machine où CHAR_BIT est de 8, il va donner 4.
sizeof(int)== 32 bits je voulais dire
OriginalL'auteur epatel
Vous avez deux 16 bits des sections (les trois premiers champs et les trois derniers champs sont en 16 bits).
C'est seulement 65536 entrées. Donc, avoir une table qui contient les bits de version inversée de la les champs. Envelopper la structure dans une union avec une autre structure qui dispose de deux 16 champs de bits pour rendre cela plus facile?
Quelque chose comme (non testé, je ne suis pas près d'un compilateur C):
De la Population de la table de recherche à gauche comme un exercice pour le lecteur 🙂
Cependant, à la lecture de votre compilateur doc soigneusement. Je ne suis pas sûr si la norme exige que la structure pour l'adapter en un mot (même si je m'attends à la plupart des compilateurs pour le faire).
Eh bien, peut-être que c'est essentiel, nous n'avons pas été dit.
OriginalL'auteur The Archetypal Paul
Vous voulez faire cela, entre le canal de fichier (ou le réseau) et à votre structure. Mon préféré de la pratique est d'isoler le fichier I/O à partir de structures d'écrire du code qui génère le fichier de tampons dans une représentation connue, et l'appariement de lire le code qui inverse cette transformation.
Votre exemple est particulièrement difficile à deviner, car la bitfields sont définis pour être unsigned int et
sizeof(unsigned int)
est particulièrement non-portable.En supposant qu'un "SWAG" qui
sizeof(int)==4
puis obtenir un pointeur vers une struct et reording les octets individuels probablement vous donner la réponse que vous voulez.L'astuce de la définition de la structure différemment pour différentes plates-formes pourrait de travail, mais dans l'exemple que vous citez il n'y a pas une rupture nette dans les limites d'octets, de sorte qu'il ne devrait pas être possible de produire l'équivalent d'une plate-forme à l'autre, sans fractionnement un ou plusieurs des champs en deux morceaux.
OriginalL'auteur RBerteig
Il devrait être suffisant pour échanger les octets. Position des bits dans un octet est le même dans les grandes et little-endian.
par exemple :
oui, ne sera pas portable. mais j'
OriginalL'auteur qwerty
Vous ne devriez pas utiliser des bits des champs lors de la disposition physique est importante, car elle est mise en œuvre définies par l'ordre dans lequel le mot est rempli.
Euh, qu'est-ce? Ils sont de codage pour un compilateur (gcc).
Cela ne veut pas répondre à l'OP de la question; l'OP aura été prise en compte.
OriginalL'auteur zvrba
Pour obtenir ce que ça va, j'ai enfin eu une solution (ce que certains dérivés de epatel la solution ci-dessus). C'est, si je convertis x86, Solaris SPARC.
Nous devons d'abord swap entrant sturcture et ensuite de lire les éléments dans l'ordre inverse.
Fondamentalement, après avoir examiné la manière dont les structures sont alligned j'ai vu que l'endianess changé à la fois dans l'ordre des octets et des bits de commande. Voici un pseudo-code.
}
Après quelques tests, j'ai trouvé que cette approche n'est valable que si les éléments de remplir complètement la structure, c'est à dire il n'y a pas les bits non utilisés.
OriginalL'auteur foo