Probleme de taille de structure avec char[] et double - C - Programmation
Marsh Posté le 24-03-2006 à 15:18:42
Problème de l'alignement des données 1,2,4,8 bytes.
Ce règle avec les options pragma pack, voir ton compilo.
Marsh Posté le 24-03-2006 à 15:21:15
y a du padding insérer par ton compilateur. soit pour un accès plus rapide, soit par obligation d'alignement. donc si tu forces ton compilateur à ne pas le faire (pragma ou attribut), sois bien sur de ton coup.
Marsh Posté le 24-03-2006 à 15:25:01
il est aussi possible de compacter la structure dans un tableau de char si tu en as besoin
Marsh Posté le 24-03-2006 à 16:00:00
si tu veux une image mémoire de ta structure dans laquel tu es sur que tout les champs sont contigues
ou inversement si tu veux lire une structure depuis une source externe (fichier) ou elle est compactée
ca evite de forcer l'alignement à la compilation (qui peux nuire aux performance) tout en gardant la possibilité de manipuler une version sans padding
Marsh Posté le 24-03-2006 à 17:55:15
skelter a écrit : si tu veux une image mémoire de ta structure dans laquel tu es sur que tout les champs sont contigues[quotemsg] donc pas une image mémoire |
bonjour la portabilité
skelter a écrit : |
va-t-en surtout mal aligné un double sur sparc
Marsh Posté le 24-03-2006 à 18:04:44
Taz a écrit : bonjour la portabilité |
Justement le mapping 'tableau de unsigned char' est garanti d'être portable. Ensuite on a une structure interne qui fait ce qu'elle peut et on recopie les champs 'à main' byte par byte en faisant les assemblages nécessaires à coup de | et de <<.
C'est sans doute pas rapide, mais c'est portable. Il suffit de fixer le format externe une fois pour toutes.
Marsh Posté le 24-03-2006 à 18:51:53
Emmanuel Delahaye a écrit : Justement le mapping 'tableau de unsigned char' est garanti d'être portable. Ensuite on a une structure interne qui fait ce qu'elle peut et on recopie les champs 'à main' byte par byte en faisant les assemblages nécessaires à coup de | et de <<. |
Il existe en php la fonction "serialize()" qui descend un objet dans une chaîne.
Ca y ressemble beaucoup non ?
Marsh Posté le 24-03-2006 à 20:16:13
> Il existe en php la fonction "serialize()" qui descend un objet dans une chaîne.
Ca y ressemble beaucoup non ?
pas tout à fait... ici il s agit de traiter un double en chaîne binaire. serialize() convertit vraiment en chaîne de caractères.
Marsh Posté le 24-03-2006 à 20:43:55
Emmanuel Delahaye a écrit : Justement le mapping 'tableau de unsigned char' est garanti d'être portable. Ensuite on a une structure interne qui fait ce qu'elle peut et on recopie les champs 'à main' byte par byte en faisant les assemblages nécessaires à coup de | et de <<. |
absolument, en fait l'erreur par rapport à ce que sous entend Taz serait de traité naivement chaque champ à coup d'affectation ou de memcpy, l'interpretation ne serait pas la meme suivant l'endianess
Marsh Posté le 24-03-2006 à 22:27:56
justement, le mapping dans un tableau ne m'est pas possible (c'est pour un TP et le prof veut absolument qu'on envoie la structure sur le socket pour voir les problemes d'endianess (communication entre x86 et SPARC))
je vais donc regarder du coté de pragma pack.
Marsh Posté le 24-03-2006 à 22:43:59
bon ça marche avec
Code :
|
par contre sur solaris gcc me balance un warning "pragma([push],[id],n) is not supported on this target", m'enfin bon ça marche c'est le principal.
Merci de votre aide
Marsh Posté le 25-03-2006 à 09:55:31
ArthurDent a écrit : justement, le mapping dans un tableau ne m'est pas possible (c'est pour un TP et le prof veut absolument qu'on envoie la structure sur le socket pour voir les problemes d'endianess (communication entre x86 et SPARC)) |
Pas besoin d'une structure pour ça. Tu écris "short i=5", tu balances "i" sur ta socket et tu regardes ton nombre à l'arrivée. Normallement, tu devrais avoir 1280 (0x0005 est devenu 0x0500)
Ensuite tu pourras épater ton prof en lui disant que tout entier long ou court qui traverse un réseau doit d'abord être converti en "représentation réseau" via la fonction
Et tout nombre arrivant du réseau doit être reconverti en nombre compréhensible par la machine via la fonction:
Pour reprendre l'exemple, précédent, tu écris "short j=htons(i)", tu balances "j" sur le réseau que tu récupères de l'autre coté dans un "short x" et tu affiches "ntohs(x)". Tu devrais retrouver ton "5"
Marsh Posté le 25-03-2006 à 10:32:33
Taz a écrit : pourquoi tu veux faire ça en fait ? |
je dois transferer ma structure via socket (sans mapping) entre une machine x86 et une SPARC et apparamment l'alignement par defaut des octets sur ces 2 machines n'est pas le meme, cela me créeait donc des decalages lorsque je voulais relire mes données coté SPARC (mon double etait decalé de 2 octets et donc le double que je lisais etait faux car ses 2 octets de poids fort correspondaient aux octets utilisés sur la x86 pour aligner et les 2 octets de poids faible correspondait aux octets de poids fort)
Sve@r a écrit : Pas besoin d'une structure pour ça. Tu écris "short i=5", tu balances "i" sur ta socket et tu regardes ton nombre à l'arrivée. Normallement, tu devrais avoir 1280 (0x0005 est devenu 0x0500)
|
oui j'utilise ces 2 fonctions pour les int et les float, mias cela ne marche pas pour les doubles
et l'utilisation de structure m'est imposé
Marsh Posté le 25-03-2006 à 15:38:01
Il y a la librairie ``xdr`` de Sun pour les échanges réseaux normalisés (RFC1014).
Marsh Posté le 25-03-2006 à 17:25:18
nargy a écrit : Il y a la librairie ``xdr`` de Sun pour les échanges réseaux normalisés (RFC1014). |
oui mais là aussi le tp nous "interdit" de l'utiliser
Marsh Posté le 25-03-2006 à 19:22:05
ArthurDent a écrit : oui j'utilise ces 2 fonctions pour les int et les float, mias cela ne marche pas pour les doubles |
C'est fun d'utiliser "ntohl()" et "htonl()" avec des float... mais puisque le prof t'intedit d'utiliser XDR il te suffit d'utiliser intelligemment "ntohs()" et "htons()" pour créer des fonctions "ntohd()" et "htond()"
Code :
|
Marsh Posté le 25-03-2006 à 19:53:40
Sve@r a écrit : C'est fun d'utiliser "ntohl()" et "htonl()" avec des float... mais puisque le prof t'intedit d'utiliser XDR il te suffit d'utiliser intelligemment "ntohs()" et "htons()" pour créer des fonctions "ntohd()" et "htond()"
|
oué nan, j'ai rien dit pour les floats.
la fonction de conversion je l'ai fait a coup de memcpy en passant la taille de la donnée en parametre afin de pouvoir le reutiliser avec autre chose que des doubles
Marsh Posté le 24-03-2006 à 15:17:30
Bonjour,
J'ai un probleme bizarre,
si je declare :
==>sizeof = 20, or je devrais avoir 18
si je fais :
==>sizeof = 11, ce qui est cohérent
==>sizeof = 16, cohérent aussi
Le problème se pose donc si je met dans ma structure un char[] et un double ou un int.
J'aimerais donc savoir d'où viennent ces 2 octets en trop car cela posent des problèmes lorsque je veux transferer ma structure via une socket.
Merci d'avance.