Len Vs LenB - CopyMemory, Structures Perso (Types), etc.
Bonjour,
Titre barbare, j'en conviens. Ce post est là pour vous initier à la gestion mémoire effectuée par le compilateur de VB6.
Pour jouer avec les APIs, on a souvent à faire avec des UDTs (User Defined Types) du genre:
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Et lorsque l'on joue en mémoire, on utilise bien souvent la longueur de la structure. On pourrait directement ici utiliser la valeur 16... mais pour des structures plus encapsulées, voir changeantes, il est plus sage de laisser à VB le soin de calculer la taille de la structure.
Lorsqu'on lit certains codes, on voit tantôt l'usage de Len, tantôt celui de LenB pour calculer cette taille.
Bien que ces deux instructions semblent toujours renvoyer la même valeur, il vaut mieux utiliser LenB.
En fait, VB aligne les champs des UDT sur 4 octets.
Conçu pour les architectures 32 bits, c'est l'octet qui est le plus petit élément adressable en mémoire, ce qui explique cette optimisation.
Len renvoie en réalité la taille cumulée des différents champs. LenB renvoie la taille prise en mémoire pour stocker la structure.
Prenons un exemple simple :
Private Type A
Start As Long
EquipementId As Long
End As Long
TblWordEquipementInData As Integer
FillByte As Byte
End Type
Private Sub Form_Load()
Dim var As A
MsgBox Len(var) => 15 donc la taille stricte des champs, additionnés
MsgBox LenB(var) => 16 la taille reele de la structure
End Sub
là, la structure est optimisée en ce sens: les champs les lus grands en premiers
en inversant simplement les champs, on obtiens:
Private Type A
TblWordEquipementInData As Integer
Start As Long
EquipementId As Long
End As Long
FillByte As Byte
End Type
on à bien sur un Len de 15
mais un LenB de 20
après TblWordEquipementInData, VB laisse donc un trou de deux octets, pour pouvoir adresser directement Start
ce qui nous fais bien 16 octets, plus 4 pour FillByte
de même:
Private Type A
TblWordEquipementInData As Integer
FillByte As Byte
FillByte2 As Byte
Start As Long
EquipementId As Long
End As Long
End Type
Donne un Len et un LenB égaux, de 16 puisque nous ne générons pas de trou.
Un CopyMemory devra donc TOUJOURS voir un LenB utilisé, sous peine de manquer des infos, décalées pour alignement.
Il faut également veiller a bien structurer les Types, pour miniser ce phénomène d'alignement.
Il ne reste plus qu'à se méfier des String, et tout est magnifique. Si vous voulez stocker du texte, privilégiez l'utilisation d'un tableau de Bytes...
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :