C: Fonte tableau d'octets à struct
J'ai le problème de la coulée d'un tableau d'octets à un struct, certains octets sont ignorées ou ignoré.
Compte tenu de la structure suivante,
typedef struct
{
uint32_t id;
uint16_t test;
uint8_t group;
uint32_t time;
uint16_t duration;
uint8_t a;
uint8_t b;
uint8_t c;
uint16_t d;
uint16_t e;
uint8_t status;
uint8_t x;
uint8_t y;
} testStruct_t, *PtestStruct_t;
J'ai un tableau avec les éléments suivants de données de test:
uint8_t pBuff = { 0x11 , 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 };
Le casting se fait comme suit:
PtestStruct_t pStruct = (PtestStruct_t)pBuff;
Quelque part dans la structure de certains octets sont ignorés ou passés sous silence. Je ne sais pas pourquoi.
Cela a été testé dans Visual Studio 2012 et sur un processeur ARM sur lesquels ce test et de débogage a été rendue nécessaire.
Ce qui me manque ici? Je ne crois pas que c'est Endian liés. Il pourrait être le compilateur dans les deux cas de test, je ne sais pas quoi faire dans ce dernier cas.
Les octets qui sont ignorés/ignorés sont 0x88
et 0x14
padding
et alignment
et (la mauvaise nouvelle, c'est le compilateur / processeur spécifique)Si vous faites cela comme montré ici, déjà, au mieux, une plate-forme et la mise en œuvre dépendant de la solution, et sans doute à tort, de toute façon (comme vous allez le découvrir). Les deux dépendant de l'implémentation de rembourrage et de l'alignement aura un effet sur le résultat que vous recherchez.
il est généralement une directive de compilation ou #pragma pour spécifier la structure de rembourrage et de l'alignement. #pragma pack(0) ou la gcc avec l'option -fpack-struct[=n] sont un couple de façons de contrôler cela. Visual Studio a aussi une option dans l'interface graphique pour définir la structure de rembourrage pour votre projet.
Le bug lui-même n'est pas endian, mais votre code s'appuie sur l'endianess et est non-portable. Que se passe dès que vous essayez d'accéder à la personne octets d'un type entier, qui est de 16 octets ou plus. Endian code indépendant ne repose pas sur des moulages, etc, mais au lieu accède octets individuels à travers le décalage de bits et bits de masquage.
(my_uint32 >> 24) & 0xFF
est par exemple la garantie de tenir l'octet le plus significatif d'un certain nombre, peu importe endianess.OriginalL'auteur Armandt | 2013-11-15
Vous devez vous connecter pour publier un commentaire.
Vous êtes à la rencontre de l'alignement de rembourrage.
Les décalages présentés ici sont susceptibles d'être mauvais. Le compilateur aura probablement lieu rembourrage entre "groupe" et le "temps" de s'assurer que le "temps" est sur une limite de 4 octets (l'alignement est configurable)
Si vous avez absolument besoin de la structure pour être comme cela, vous pouvez utiliser
#pragma pack
Merci beaucoup :), très apprécié
OriginalL'auteur kfsone
Compilateur a peut-être ajouté quelques octets entre votre struct champs pour l'alignement.
Vous avez besoin d'utiliser un emballage pour empêcher le compilateur de faire padding - ce doit être explicitement demandée - sous GCC c'est attribut((paniers)),
exemple:
et pour Visual Studio consulter MSDN
OriginalL'auteur alexbuisson