2016-07-28 1 views
0

je le struct suivant:Copier une struct dans un tampon d'octets

struct sample { 
    uint8_t four; 
    bool b; 
    uint8_t two; 
}; 

Pour envoyer un paquet udp, je dois emballer ces valeurs dans un seul octet:

| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 
+---+---+---+---+---+---+---+---+ 
|  four  | 0 | b | two | 
+---------------+---+---+-------+ 

Quelle est le meilleur moyen de copier les valeurs de structure dans cet octet? Je vérifie la condition préalable avant de le faire ainsi aucune donnée ne devrait être perdue en copiant uint8_t des valeurs dans moins d'espace.

Répondre

5

Je voudrais simplement utiliser une fonction:

uint8_t pack(const sample &s) 
{ 
    return (s.four & 0xF) | (s.b << 5) | ((s.two & 3) << 6); 
} 

que vous avez dit que la plage de données est cochée, vous pouvez simplifier cela à:

return s.four | (s.b << 5) | (s.two << 6); 
2

Étant donné que votre code n'est pas de toute façon portable, vous pourriez tout aussi bien utiliser les champs de bits ici:

struct sample { 
    uint8_t four:4; 
    bool empty:1; 
    bool b:1; 
    uint8_t two:2; 
}; 

Je ne suis pas fan de champs de bits, mais ils semblent être applicables dans votre cas.

+1

Ne devrait-il pas être «vide» avant «b»? – Slava

+0

@Slava, certainement. Fixe, merci. – SergeyA

+1

Pourquoi n'est pas portable? – Jepessen

0

Votre commande bits est représenté dans une ... unique, façon. Habituellement, lorsque nous exprimons des valeurs en binaire, les bits inférieurs sont affichés sur la droite. Tant que vous empaquetez et déballez les données, vous pouvez choisir votre ordre de bits. Méfiez-vous de l'ordre du réseau par rapport à l'ordre du système si. Alors que l'ordre des bits dans les octets est le même sur chaque plate-forme, l'ordre des octets peut changer.

Vous devez connaître votre application pour déterminer si l'emballage/déballage en vaut la peine. Plus de calcul sur chaque côté et en fonction des intervalles entre les paquets UDP et combien de données sont empaquetées dans chaque paquet UDP, il ne peut pas en valoir la peine. Si vous essayez simplement de sauvegarder des données pour une application cellulaire, eh bien, merci: @)

J'évite toujours de déplacer des booléens en raison de la paranoïa de la plate-forme/du compilateur. Pourrait utiliser quelque chose comme s.b? 32: 0 à la place.

+0

J'essaie de créer des paquets CIGI, et la norme a beaucoup de paquets construits de cette façon ... – Jepessen

+0

Désolé, un peu d'un lapsus cérébral. Les paquets de réseau sont toujours écrits de cette façon –