Les structures en détail dans eForth Windows
publication: 29 novembre 2024 / mis à jour 29 novembre 2024
Dans le précédent chapitre, nous avons abordé les structures construites avec struct
et field
.
On va analyser plus en détail certaine subtilités sur la manipulation des structures, en particulier sur l'accès aux données,
en lecture et écriture.
Les tailles de champs
Windows exploite abondamment les structures pour échanger des données entre processus. Ici un exemple de structure partagé avec l'API Windows:
struct POINT i32 field ->x i32 field ->y struct RECT i32 field ->left i32 field ->top i32 field ->right i32 field ->bottom struct MSG ptr field ->hwnd i32 field ->message i16 field ->wParam i32 field ->lParam i32 field ->time POINT field ->pt i32 field ->lPrivate
Ce code est extrait des fichiers source de eForth Windows. Ici, sont définies trois structures:
POINT
RECT
et MSG
.
Pour rappel, avant chaque field
, on a un mot qui indique la taille du champ dans la structure:
- i8 pour un champ de 8 bits, c'est à dire 1 octet;
- i16 pour un champ de 16 bits, donc de 2 octets;
- i32 pour un champ de 32 bits, donc 4 octets;
- i64 et ptr pour un champ de 64 bits, donc 8 octets;
Le mot ptr
dépend de la version FORTH. Ici, dans eForth Windows, c'est bien un champ 64 bits. Mais sur un
système 32 bits, comme ESP32forth, ce sera un champ 32 bits.
Dans la structure MSG
, on retrouve des champs de différente taille:
ptr field ->hwnd
désigne un champ 64 bitsi32 field ->message
désigne un champ 32 bitsi16 field ->wParam
désigne un champ 16 bits
Pour chaque taille de champ, il faut utiliser les mots @
ou !
adaptés à la taille du champ cible.
Accès aux données dans les champs d'une structure
On l'a compris, il faut un mot adapté à chaque taille de données:
- 8 bits: accès avec les mots
C@
etC!
- 16 bits: accès avec les mots
SW@
ouUW@
etW!
- 32 bits: accès avec les mots
SL@
ouUL@
etL!
- 64 bits: accès avec les mots
@
et!
Exemple:
create iconePos POINT allot -5 iconePos ->x W! 3 iconePos ->y W!
On stocke la valeur -5 dans le premier champ 16 bits, la valeur 3 dans le secopnd champ 16 bits. Pour récupérer ces valeurs, il faut procéder ainsi:
iconePos ->x SW@ iconePos ->y SW@
Pour récupérer une valeur 16 bits, il y a deux options. Utiliser SW@
ou UW@
.
Le mot SW@
récupère la valeur 16 bits, en tant que valeur signée.
Si on avait utilisé UW@
, la valeur -5 aurait été remplacée par 65531 qui est sont équivalent non signé sur 16 bits.
Le mécanisme est similaire pour les valeurs 32 bits avec SL@
et UL@
.
Gérer les accesseurs de structures
Si vous devez accéder aux données d'une structure en différents endroits de votre programme, la meilleure solution est de définir un seul mot d'accès et ensuite passer exclusivement par ce mot. Exemple:
: setPoint ( x y addr -- ) >r r@ ->y W! r> ->x W! ; : getPoint ( addr -- x y ) >r r@ ->x SW@ r> ->y SW@ ; -15 37 iconePos setPoint iconePos getPoint \ push -15 37 on stack
Dans le reste du programme, l'utilisation de setPoint
et getPoint
rendra bien plus facile
la manipulation des données d'une structure POINT
.
Les structures impriquées
L'API Windows exploite des structures imbriquées:
struct MSG ptr field ->hwnd i32 field ->message i16 field ->wParam i32 field ->lParam i32 field ->time POINT field ->pt i32 field ->lPrivate
Dans cette structure MSG
, est défini un champ ->pt
. Ce champ
a comme taille de données celle d'une structure POINT
. Pour rappel, l'utilisation
d'un nom de structure restitue simplement la taille des données de cette structure. Ici, le
mot POINT
restitue la valeur 8, valeur qui correspond à la taille des deux champs 32 bits définis dans
cette structure POINT
.
Voyons un exemple simple de structure imbriquée. Utilisons POINT
pour définir une structure TRIANGLE
:
structures
struct TRIANGLE
POINT field ->triangle-pt1
POINT field ->triangle-pt2
POINT field ->triangle-pt3
: setTriangle ( x1 y1 x2 y2 x3 y3 addr -- )
>r
r@ ->triangle-pt3 setPoint
r@ ->triangle-pt2 setPoint
r> ->triangle-pt1 setPoint
;
create triAng01
TRIANGLE ALLOT
10 10 70 10 40 70 triAng01 setTriangle
Dans certains cas, c'est un peu moins élégant. Voici l'accès aux données d'une structure de type
TRIANGLE
sans passer par setPoint
:
: setTriangle ( x1 y1 x2 y2 x3 y3 addr -- )
>r
r@ ->triangle-pt3 ->y W!
r@ ->triangle-pt3 ->x W!
r@ ->triangle-pt2 ->y W!
r@ ->triangle-pt2 ->x W!
r@ ->triangle-pt1 ->y W!
r> ->triangle-pt1 ->x W!
;
En résumé, les structures sont à manipuler avec soin. Réservez-les pour les interfaces avec les liaisons logicielles des API Windows.
Legal: site web personnel sans commerce / personal site without seling