Utilisation de Memcpy et type de données [Résolu]

Signaler
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008
-
mush74
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008
-
Bonjour,

Un petit probleme (surement simple, étant nioub) a vous soumettre :

Je dispose d'une structure de ce type :

typedef unsigned short int   uint16;
typedef unsigned long int    uint32;

typedef struct
{
   uint32   d1;
   uint16   d2;
   uint32   d3;
} data;

Je reçois dans un tableau "tab" 10 octets. Donc de la meme taille que ma structure.

Lorsque je fais un memcpy(&data, &tab[0], 10); je m'attends a remplir ma structure avec les valeurs du tableau. Mais voila, ca ne marche pas du tout.En fait, lorsque je demande l'affichage des adresses mémoire de d1, d2 et d3, je m'appercois que je vais toujours de 4 octets en 4 octets.
Ex : 0x80000000, 0x80000004, 0x80000008.

Or, vu que d2 a une taille de 2 octets, je pensais obtenir plutot :
Ex : 0x80000000, 0x80000004, 0x80000006.

Evidemment, comme cela ne fonctionne pas, la valeur de data.d1 est correcte, mais après data.d2 et data.d3 sont fausses...

Le pire, c'est qu'en changeant d1 en type long, je passe bien a 8 octets:
Ex : 0x80000000, 0x80000008, 0x8000000b.

Au secours.

7 réponses

Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
10
Bonjour,


Tu peux gérer la valeur de l'alignement.

Ca risque de dépendre du compilo, mais pour VC, il y a pragma pack.

Tu peux l'utiliser comme ça :
#include <stdio.h>
#include <stdlib.h>

typedef unsigned short int uint16;
typedef unsigned long int uint32;

typedef struct
{
uint32 d1;
uint16 d2;
uint32 d3;
} data;

#pragma pack(1)
typedef struct
{
uint32 d1;
uint16 d2;
uint32 d3;
} datap;
#pragma pack()

int main()
{
printf("Alignement par defaut : %d\n", sizeof(data));
printf("Alignement sur un octet : %d\n", sizeof(datap));
system("pause");
}


Ce genre de truc est a faire seulement si on est obligé, car cela peut fortement affecter les performances.
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
16
Normal tout ceci comme expliqué déjà plusieurs fois sur ce forum.

Ta struct est bancale, les données sont mal alignées alors ton compilo les a correctement alignées sur 4.

Ta struct est donc en réalité:
typedef struct
{
  uint32   d1;
  uint16   d2;
  uint16   dummy;
  uint32   d3;
} data;

Il faut écrire:
typedef struct
{
  uint32   d1;
  uint32   d3;
  uint16   d2;
} data;
si tu ne veux pas que le compilo y retouche.

ciao...
BruNews, MVP VC++
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008

Complément d'info :
Je recois des valeurs dans un buffer (tableau). Ces données proviennent d'un GPS et envoie des trames au format Garmin. Les données sont envoyées "en série" de longueur variable, et placée dans une structure (nommé PVT data par Garmin) qui mélange les données de 16, 32 et 64 bits dans un ordre bien particulier.
 Donc a part faire un découpage de chaque valeur, il n'y a pas d'autres solutions ? Dans la trame Garmin, il n'y a pas de donnée "dummy". Meme si le découpage donnée par donnée peut fonctionner, je trouvais cela un peu "bricolage".

Enfin merci tout de même pour l'explication !!!
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
16
Clair que si le format ne dépend pas de soi, il ne reste que pragma pack.

Attention que dans les données GPS, il y a du BigEndian mixé avec du LittleEndian dans les structures, c'est le souk.

ciao...
BruNews, MVP VC++
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008

Je vais essayer tout cela. Cela dit je suis sous Ubuntu / GCC 4.2 / Code::Blocks. Donc je ne pense pas que cette directive s'applique. Mais au pire il y a surement un équivalent. je vais chercher un peu et je repost dès que j'ai la solution.

A+
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
10
Je viens de tester sous gcc/Code::Blocks/XP.
Aucun problème.
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008

#pragma pack a résolu mon probleme...

Je dispose enfin des bonnes valeurs de mon antenne GPS !!!

Merci a vous deux !