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

maaping struct en format binaire ne peut pas être fait sans soin. Vous devriez lire à propos de 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