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

mush74 12 Messages postés mercredi 7 novembre 2007Date d'inscription 8 mars 2008 Dernière intervention - 6 mars 2008 à 12:40 - Dernière réponse : mush74 12 Messages postés mercredi 7 novembre 2007Date d'inscription 8 mars 2008 Dernière intervention
- 7 mars 2008 à 12:05
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.
Afficher la suite 

Votre réponse

7 réponses

Meilleure réponse
cs_rt15 3982 Messages postés mardi 8 mars 2005Date d'inscription 7 novembre 2014 Dernière intervention - 6 mars 2008 à 14:05
3
Merci
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.

Merci cs_rt15 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 72 internautes ce mois-ci

Commenter la réponse de cs_rt15
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 6 mars 2008 à 12:50
0
Merci
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++
Commenter la réponse de BruNews
mush74 12 Messages postés mercredi 7 novembre 2007Date d'inscription 8 mars 2008 Dernière intervention - 6 mars 2008 à 13:32
0
Merci
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 !!!
Commenter la réponse de mush74
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 6 mars 2008 à 14:19
0
Merci
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++
Commenter la réponse de BruNews
mush74 12 Messages postés mercredi 7 novembre 2007Date d'inscription 8 mars 2008 Dernière intervention - 7 mars 2008 à 10:57
0
Merci
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+
Commenter la réponse de mush74
cs_rt15 3982 Messages postés mardi 8 mars 2005Date d'inscription 7 novembre 2014 Dernière intervention - 7 mars 2008 à 11:09
0
Merci
Je viens de tester sous gcc/Code::Blocks/XP.
Aucun problème.
Commenter la réponse de cs_rt15
mush74 12 Messages postés mercredi 7 novembre 2007Date d'inscription 8 mars 2008 Dernière intervention - 7 mars 2008 à 12:05
0
Merci
#pragma pack a résolu mon probleme...

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

Merci a vous deux !
Commenter la réponse de mush74

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.