Aurel184
Messages postés21Date d'inscriptiondimanche 14 mars 2004StatutMembreDernière intervention 9 juin 2010
-
23 févr. 2007 à 12:13
Aurel184
Messages postés21Date d'inscriptiondimanche 14 mars 2004StatutMembreDernière intervention 9 juin 2010
-
23 févr. 2007 à 14:11
Bonjour,
je développe une interface en Delphi permettant de contrôler par réseau ou port série des vidéoprojecteurs professionnels. Quand j'envoi une commande, le projecteur me répond. C'est au moment de la gestion de la réponse que se trouve mon problème.
Le projecteur m'envoie une chaîne binaire de 33 octets. Je stocke cette chaîne dans une structure :
La fonction SizeOf() renvoie bien 33 octets comme taille de structure. Comme l'aide Delphi dit que le type Word est en entier non signé de 16bits et le longWord un entier non signé de 32 bits, j'ai modifié ma structure :
Et là SizeOf() renvoie 36 octets comme taille de structure. Et les données sont décallées et donc non traitable. Ma question : Est ce que j'aurait raté quelque chose sur le codage des Word ? Où sont les 3 octets qui sont apparus dans la deuxième forme de ma structure ? Merci d'aclairer ma lanterne.
florenth
Messages postés1023Date d'inscriptiondimanche 1 août 2004StatutMembreDernière intervention17 août 20083 23 févr. 2007 à 13:04
Salut,
Ahah, en voila une question qu'elle est intéréssante !
En fait, Delphi aligne les données des structures "record" en fonction de la valeur de la directive de compilation {$A}.
Par défaut, en mode {$A+}, les différents champs de ta structure qui font plus d'un octet sont alignés sur les frontières des quadruples mots.
Concrètement, cela signifie que Delphi ajoute des zéros entre tes différents champs pour optimiser l'accès mémoire.
Dans ta première version, comme tu n'utilises que des Byte, rien ne dépasse un octet en taille. Mais dans la deuxième, l'utilisation de Word et Longword fait que Delphi va aligner tes champs, d'où le problème que tu rencontres.
Dans certains cas, comme le tien, la taille de l'entegistrement est importante et doit être fixe.
Pour pallier à ce problème, il faut le signaler à Delphi en utilisant le modificateur "packed" devant la déclaration.
Ce qui donne pour ton type :
-----------------------------
TBinaire = packed record // <== Ajout du mot "packed"
Response : Byte;
Header : array [0..4] of Byte;
CRC : Word;
OperationType : Byte;
OperationNumber : Word;
OperationValid : Byte;
NotUsed : array [0..4] of Byte;
OperationValue : Word;
OparationValueNotUsed : Word;
LowerLimit : Cardinal;
UpperLimit : Cardinal;
Increment : Cardinal;
end;
-----------------------------
Et là, ton type fait bien 33 octets comme demandé...
Un conseil en plus :
- Evite les underscore dans les noms de champs, c'est inutile et plus dur à lire.
- Le type Cardinal est un type natif qui correspond au type Longword donc tu peux tout remplacer tes Longword en Cardinal (de même, les HRESULT sont en fait des Integer, etc...)