[résolu] Problème de bitfields et d'alignement

Problème de bitfields et d'alignement [résolu] - C - Programmation

Marsh Posté le 06-10-2008 à 16:37:17    

Bonjour,
 
Je suis en train de mettre au point du code pour parser des tables SI/PSI que je reçois en DVB.
Pour ça, au lieu d'utiliser des masques et des shifts, je voudrais utiliser des bitfields ; voici un exemple simplifié :
 

Code :
  1. struct huhu
  2. {
  3. unsigned char table_id      :8;
  4. unsigned char section_syntax_indicator  :1;
  5. unsigned char dummy       :1;
  6. unsigned char reserved1      :2;
  7. unsigned char section_length_hi    :4;
  8. };
  9. void parseTest()
  10. {
  11. huhu table;
  12. unsigned char stream[ 2 ] = { 0, 0xB0 };
  13. memcpy( &table, (huhu*)stream, sizeof(huhu) );
  14. }


 
Ce que je suis censé obtenir est (0xB0 vaut 10110000 en binaire):
table_id : 0
section_syntax_indicator : 1
dummy : 0
reserved1 : 3
section_length_hi : 0
 
Le problème est que j'obtiens :
table_id : 0
section_syntax_indicator : 0
dummy : 0
reserved1 : 0
section_length_hi : 0x0B
 
Je travaille avec Visual Studio 2005.
 
Est-ce que vous auriez une idée du problème ? C'est un soucis d'alignement ?
Merci d'avance.


Message édité par Riot le 07-10-2008 à 13:44:16

---------------
Be the one with the flames.
Reply

Marsh Posté le 06-10-2008 à 16:37:17   

Reply

Marsh Posté le 06-10-2008 à 16:48:46    

c'est plutôt un souci d'endianess, il me semble

Reply

Marsh Posté le 06-10-2008 à 17:48:37    

Oui mais si je remplace
unsigned char stream[ 2 ] = { 0, 0xB0 };
par
unsigned char stream[ 2 ] = { 0, 0x0B };
je n'obtiens pas le résultat attendu, mais ceci :
table_id : 0
section_syntax_indicator : 1
dummy : 1
reserved1 : 2
section_length_hi : 0


Message édité par Riot le 06-10-2008 à 18:17:39

---------------
Be the one with the flames.
Reply

Marsh Posté le 06-10-2008 à 17:58:41    

Ca me semble pourtat être précisément le résultat à attedre das les deux cas, ce que tu obtiens ...
 
quand tu déclares tes bitfields, rappelle-toi bien que tu commences par les bits de poids faible. Ce que tu copies dans ta structure au final, c'est ca :
1011 0000 0000 0000
 
donc tes 4 bits de poids le plus fort valent 0xB comme prévu.
 
Je ne vois pas comment ca aurait pu se transformer en ca : 0000 1101 0000 0000


Message édité par theshockwave le 06-10-2008 à 17:59:13
Reply

Marsh Posté le 06-10-2008 à 18:09:01    

Mais c'est quoi ton résultat attendu ?

Reply

Marsh Posté le 06-10-2008 à 18:16:23    

Ok, donc tu me dis que pour obtenir ce que je souhaite, il faut que j'inverse mes bits de poids fort et de poids faible dans ma structure ?

 

En passant de :

Code :
  1. struct huhu
  2. {
  3. unsigned char table_id      :8;
  4. unsigned char section_syntax_indicator  :1;
  5. unsigned char dummy       :1;
  6. unsigned char reserved1      :2;
  7. unsigned char section_length_hi    :4;
  8. };
 

à :

Code :
  1. struct huhu
  2. {
  3. unsigned char table_id      :8;
  4. unsigned char reserved1      :2;
  5. unsigned char dummy       :1;
  6. unsigned char section_syntax_indicator  :1;
  7. unsigned char section_length_hi    :4;
  8. };
 

C'est bien ça ?

  

Pour Taz, à partir de "00B0", je veux que ma structure soit remplie de la sorte :
table_id : 0
section_syntax_indicator : 1
dummy : 0
reserved1 : 3
section_length_hi : 0

 

edit : je voulais dire "0B0" et pas "00B0"


Message édité par Riot le 06-10-2008 à 20:46:07

---------------
Be the one with the flames.
Reply

Marsh Posté le 06-10-2008 à 18:37:54    

0x00B0 n'est pas équivalent à { 0, 0xB0}

Reply

Marsh Posté le 06-10-2008 à 20:45:42    

Boulette, je voulais écrire "0B0".


---------------
Be the one with the flames.
Reply

Marsh Posté le 07-10-2008 à 12:54:48    

Le C ne définit pas par quel côté un bit field commence. Pour certain compilos les champs déclarés en premier sont les bits de poid faible, pour d'autres (genre xlc) ce sont les bits de poid fort.

Reply

Marsh Posté le 07-10-2008 à 13:43:30    

Ouais, je pense que c'est vraiment trop peu sûr pour que je mette ça en place.

 

Pour info, j'ai trouvé la solution. Il faut inverser les champs comme suit :

Code :
  1. struct huhu
  2. {
  3. unsigned char table_id      :8;
  4. unsigned char section_length_hi    :4;
  5. unsigned char reserved1      :2;
  6. unsigned char dummy       :1;
  7. unsigned char section_syntax_indicator  :1;
  8. };
 

En gros on dirait que dès que la taille des champs est inférieure à l'octet, il faut inverser l'ordre.

 

Merci pour votre aide.


Message édité par Riot le 07-10-2008 à 13:43:47

---------------
Be the one with the flames.
Reply

Marsh Posté le 07-10-2008 à 13:43:30   

Reply

Marsh Posté le 07-10-2008 à 17:43:12    

pour ton architecture particulière.

Reply

Marsh Posté le 07-10-2008 à 18:38:47    

mea culpa, je me souvenais d'une page de la msdn (pas celle ci, mais une qui exprimait une idée approchante : http://msdn.microsoft.com/en-us/library/ewwyfdbe.aspx )
mais effectivement, il est écrit noir sur blanc dans le K&R que c'est à la discrétion de l'implémentation :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed