Accueil > Forum > > > > CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?
CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?
mardi 30 juin 2009 à 15:53:23 |
CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

NHenry
|
Bonjour, J'ai actuellement la maintenance d'un projet professionnel codé en VB6. Ce projet est composé de plusieurs applications communicantes entre elles par Winsock. Les données échangées sont des structures "sérialisées" par CopyMemory. Ces structures peuvent contenir d'autres structure, etc... en cascade. Le problème est que durant la (dé)sérialisation il arrive parfois de ne pas retrouver toutes les données : Exemple avec une structure qui me pose problème : Elle est composée de plusieurs éléments et se termine par un Long nommé "End". Quand je regarde pour connaitre sa position (et aussi pour connaitre la taille de la structure), je ne comprends plus rien : VarPtr(toto.End) - VarPtr(toto) = 31612 Recherche de la position dans le tableau résultant du CopyMemory dans un Byte() : 30912 Donc le champs n'est pas mis au même endroit, là je ne comprend pas. Pour la taille de la structure, j'arrive à : Len(toto) = 29899 LenB(toto) = 31616 Mon problème est que je ne veux pas faire un buffer overflow, mais que je veux transférer toutes mes données. Quelle(s) valeur(s) dois-je prendre ?La position détectée ne correspond à aucunes valeurs (ni Len, ni LenB), et dans le tableau de résultat, dans les 4 derniers octets (même les 8 derniers), il y a que la valeur 0 donc pas mon Long. Merci d'avance pour votre aide.Pour information voici le code utilisé pour recherché l'élément dans le tableau d'octet de résultat : ReDim ltData(0 To Max(Len(toto), LenB(toto))) For j = 0 To 255 ltPosition(j) = -1 '------------------------------------ toto.End = j '------------------------------------ CopyMemory ltData(0), toto, UBound(ltData) - LBound(ltData) + 1 For i = LBound(ltData) To UBound(ltData) If ltData(i) = j Then ltPosition(j) = i Exit For End If Next i Next j
Ce code parcours les 256 possibilité d'un octet pour éviter les détections erronées et retourne le résultat dans le tableau ltPosition.
|
|
mardi 30 juin 2009 à 16:28:38 |
Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

Renfield
|
quelle est la structure ? quels en sont les champs ?
|
|
mardi 30 juin 2009 à 16:44:52 |
Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

NHenry
|
Bonjour, Pour faire court (si tu veux plus d'élément, je peux te passer ça en privé) : Public Type TServeurData Start As Long EquipementId As Long IlotInData As TAutomationInDataIlot IlotInId As Long QuaiInId(MAX_QUAIS_ILOT + 1) As Long QuaiInData(MAX_QUAIS_ILOT + 1) As TAutomationInDataQuai 'Code masqué TblWordEquipementInData(EQUIPEMENT_WORD_TABLE_LEN_IN) As Integer TblWordEquipementOutData(EQUIIPEMENT_WORD_TABLE_LEN_OUT) As Integer PipeInId As Long FillByte(336) As Byte Dummy As Long ' do not remove End As Long End Type Toutes les chaines et tous les tableaux contenus dans les sous structures sont de taille fixe. Bien que nommer une variable "End" ne sois pas forcément super, ça fonctionne en essayant avec Dummy : 31608 - 30908 - 29899 - 31616 et pour End c'était : 31612 - 30912 - 29899 - 31616 La position est bien décalée de 4 octets, et la taille est la même. Merci de t'intéresser à mon problème. 
|
|
mardi 30 juin 2009 à 17:04:13 |
Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

Renfield
|
VB aligne très certainement les champs de tes structures sur 4 octets, pour y acceder plus facilement (sans avoir a faire des masques), ce qui explique peut etre ces trous.
gaffe également a la representation mémoire d'un Long (Little/Big Endian, etc.)
le fait que tu aies des sous structures n'aide pas non plus, a mon humble avis.
|
|
mardi 30 juin 2009 à 20:17:28 |
Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

NHenry
|
Bonjour, Donc la structure fait quelle taille ? 30916 octets ? et comment en être sûr et récupérer la valeur automatiquement, car j'ai plusieurs structures et c'est énormément utilisé dans l'application ? Concernant la représentation, ce n'est pas le problème (d'un coté on passe de Type à Byte(), puis en face, Byte() à Type). 
|
|
mardi 30 juin 2009 à 22:04:00 |
Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

NHenry
|
Bonjour, Suite à une discussion sur le chan #programmation, et l'aide de MyGoddess, je vais essayer de passer tout ça en classes. Je donnerais plus d'informations demain. 
|
|
mercredi 1 juillet 2009 à 07:44:36 |
Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

Renfield
|
c'est bien une histoire d'alignement des structures, pour acceder plus facilement a la mémoire :
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
en organisant:
Private Type A
TblWordEquipementInData As Integer
FillByte As Byte
Start As Long
EquipementId As Long
End As Long
End Type
donc l'Integer et le Byte qui se suivent, les 2 octets nécessaire après l'Integer pour aligner le Long sont comblés par 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.
|
|
mercredi 1 juillet 2009 à 09:32:44 |
Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

NHenry
|
Bonjour, Merci pour tes explications. Mais cela n'explique pourquoi avec VarPtr, je trouve 31608 pour la position de ma variable, et 30908 en recherchant dans le tableau copié. Donc si j'utilise la taille de LenB, pas de risque de bufferoverflow. ? Car d'après l'analyse de la position du champ, il y a quand même 700 octets d'écart. 
|
|
mercredi 1 juillet 2009 à 09:35:38 |
Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

Renfield
|
si c'est un champ d'une sous-structure ou d'un tableau, possible, j'imagine, la mémoire est allouée selon la place libre, donc...
|
|
mercredi 1 juillet 2009 à 10:01:11 |
Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

NHenry
|
Réponse acceptée !
J'ai refais quelques tests : Résultats : VarPtr - RecherchePosition - Len - LenB Champ testé : Dummy Private Type TTest Chaine1 As String * 96 Chaine2 As String * 96 Dummy As Long End Type 384 - 192 - 196 - 388 Me serais-je trompé ? Private Type TTest TblWordEquipementInData As Integer FillByte As Byte FillByte2 As Byte Start As Long EquipementId As Long Dummy As Long End Type 12 -12 - 16 - 16 Là OK Private Type TTest FillByte As Byte FillByte2 As Byte Start As Long TblWordEquipementInData As Integer EquipementId As Long Dummy As Long End Type 16 - 16 - 16 - 20 Private Type TTest FillByte As Byte FillByte2 As Byte TblWordEquipementInData As Integer Start As Long EquipementId As Long TestStr As String * 8 Dummy As Long End Type 28 - 20 - 24 - 32 Private Type TTest FillByte As Byte FillByte2 As Byte TblWordEquipementInData As Integer Start As Long EquipementId As Long TestStr As String * 8 ByteArray(0 To 7) As Byte Dummy As Long End Type 36 - 28 - 32 - 40 Private Type TTest1 FillByte As Byte FillByte2 As Byte TblWordEquipementInData As Integer End Type Private Type TTest FillByte As Byte FillByte2 As Byte TblWordEquipementInData As Integer Start As Long EquipementId As Long SousType As TTest1 Dummy As Long End Type 16 - 16 - 20 - 20 Ça se comprend sans pb. Private Type TTest1 FillByte As Byte TblWordEquipementInData As Integer FillByte2 As Byte End Type Private Type TTest FillByte As Byte FillByte2 As Byte TblWordEquipementInData As Integer Start As Long EquipementId As Long SousType As TTest1 Dummy As Long End Type 20 - 20 - 20 - 24 Private Type TTest1 FillByte As Byte FillByte2 As Byte TblWordEquipementInData As Integer End Type Private Type TTest FillByte As Byte FillByte2 As Byte TblWordEquipementInData As Integer Start As Long EquipementId As Long SousType(0 To 3) As TTest1 Dummy As Long End Type 28 - 28 - 32 - 32 Logique Private Type TTest1 FillByte2 As Byte TblWordEquipementInData As Integer FillByte As Byte End Type Private Type TTest FillByte As Byte FillByte2 As Byte TblWordEquipementInData As Integer Start As Long EquipementId As Long SousType(0 To 4) As TTest1 Dummy As Long End Type 44 - 44 - 36 - 48 C'est clair que le Len est un peu à coté de la plaque Private Type TTest1 FillByte2 As Byte FillByte As Byte TblWordEquipementInData As Integer End Type Private Type TTest FillByte As Byte FillByte2 As Byte TblWordEquipementInData As Integer Start As Long EquipementId As Long TestStr As String * 9 SousType(0 To 4) As TTest1 Dummy As Long End Type 52 - 44 - 45 - 56 Suite à ces tests, il apparait clairement que VatPtr et LenB sont toujours d'accord. Reste toujours mon CopyMemory qui me met ma variable selon une logique qui m'échappe. Il semblerais que ce soit les String qui mettent un peu le boxon, car le Len prend un caractère = 1 octet (comme le CopyMemory) alors que LenB ( et VarPtr) considèrent 2 octets (unicode ou alignement des octets ?). Et si on ajoute à cela l'alignement, on arrive à un résultat surprenant. Donc pour faire suite à mon message précédent, c'est un effet pervers qui pose pb. Je vais essayer pour voir avec CopyMemory si LenB ne risque pas de bufferOverflow. 
|
|
Cette discussion est classée dans : toto, structure, copymemory, len, ltdata
Répondre à ce message
Sujets en rapport avec ce message
Structure contenant un pointeur [ par ywillener ]
Bonjour,J'ai besoin d'accéder à la fonction d'une DLL ayant comme paramètre une structure contenant un pointeur void. Cela peut être un pointeur vers
Dimentionnement Dynamique dans une Structure [ par biishop ]
Daius Salut a tous, Voila je me rappel plus ( j'ai du surement le savoir je pense ) comment realiser un redimentionnement ( en dynamique ) d'un tabl
Remplacement de copymemory [ par popeye63 ]
Bonjour,je recherche une solution pour utiliser copymemory voici mon code :j'ai une structure du type qui se situe dans la classe C_StrucPublic<font c
API Getusername et string -_- [ par KokoJacK ]
Bonjour j'vous montre mon problème qui est incompréhensible pour ma part -_-Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserName
Execution impression une seule fois [ par scm ]
BonjourJe programme dans VB6, mon souci est comment peut on faire si j'ai deux enregistrements A.toto, A.tata, lors de la premiere validation de A.tot
Envoi de mail [ par benjamin28 ]
BonjourJ'utilise un script vbs pour envoyer un mail avec une piece jointe :----------------------------------------------------------On Error Resume N
Copier-Coller de graphique [ par likemonster ]
Bonjour, j'ai réalisé un fichier excel contenant une page "Structure" vierge de valeur à l'ouverture! Quand j'active ma macro, la feuille structure tr
longueur structure [ par Guigar ]
Bonjour a tousj'ai une structure qui elle meme est composé de plusieur tableau, entier et autre structure (qui elle meme sont aussi composé de plein d
Quelle structure pour ma gestion commerciale? [ par damiengarnier ]
Bonjour,J'ai déjà posé quelques questions concernant mon projet mais je bute sur quelques problèmes alors je pose les choses à plat pour être sûr d'al
vb et word [ par kamovb ]
salut tous le mondej'ai besoin de votre aide SVP!j'ai un code d'enregistrement comme cela:open"c:\facture" for random access read write as #1 len=len(
Livres en rapport
|
Derniers Blogs
QUELQUES TRUCS INTéRESSANTS (05/09/2010)QUELQUES TRUCS INTéRESSANTS (05/09/2010) par coq
Cette fois-ci : .NET Debug / Performance Sécurité SQL Server .NET Determining if a type is defined in the .NET Framework (blog de Scott Dorman) Ha tiens, je n'avais jamais vraiment pensé à utiliser le jeton de clé publique...
Cliquez pour lire la suite de l'article par coq ENUMERABLECOLLECTIONENUMERABLECOLLECTION par Matthieu MEZIL
Prenons le scénario suivant. On utilise MVVM. On a les deux classes suivantes dans le model : public class Child { } public class Parent { private ObservableCollection < Child > _children; public ObservableCollection < Child > Children { get {...
Cliquez pour lire la suite de l'article par Matthieu MEZIL [HS] CHROME 6 + MOI = COUP DE GUEULE ![HS] CHROME 6 + MOI = COUP DE GUEULE ! par JeremyJeanson
Attention, le poste qui suit n'est pas la complainte d'une personne : Qui n'aime pas Chrome. D'un anti Google. D'un développeur qui a un poil énorme dans la main. Ceux qui me fréquentent savent que je change de navigateur favori tous les 2 ou 3 mois afin ...
Cliquez pour lire la suite de l'article par JeremyJeanson [WP7] UTILISER UN WRAPPANEL DANS UNE APPLICATION WINDOWS PHONE 7[WP7] UTILISER UN WRAPPANEL DANS UNE APPLICATION WINDOWS PHONE 7 par Audrey
Lors de la réalisation de ma 2ème application Windows Phone 7, j'ai souhaité utiliser un WrapPanel pour afficher plusieurs photos. Mais le contrôle WrapPanel ne fait pas parti de la liste des contrôles inclus dans le SDK de la version Beta des outils pour...
Cliquez pour lire la suite de l'article par Audrey [WP7] BESOIN D'AVOIR DES DONNéES EN CACHE[WP7] BESOIN D'AVOIR DES DONNéES EN CACHE par Nicolas
Les développeurs ASP.NET ont l'habitude de mettre des données en cache pour éviter de requêter a chaque fois la base de données. Et il est toujours utilie de penser que vos utilisateurs mobiles n'ont pas troujours une super connexion 3G/WIFI et un for...
Cliquez pour lire la suite de l'article par Nicolas
Forum
DATAREPORTDATAREPORT par NSUADI
Cliquez pour lire la suite par NSUADI
Logiciels
WebLogAndPass (1.0.0)WEBLOGANDPASS (1.0.0)WebLogAndPass est un logiciel permettant de mémoriser vos sites préférés et pour chacun d'entre-e... Cliquez pour télécharger WebLogAndPass uTorrent (2.0.4)UTORRENT (2.0.4)C'est un client BitTorrent très puissant et très performant. Comme son nom l'indique, uTorrent (m... Cliquez pour télécharger uTorrent Bureau de Gestion - ERP Devis Facturation (2.02)BUREAU DE GESTION - ERP DEVIS FACTURATION (2.02)- Version gratuite du 10/06/2010
Le Bureau de Gestion est un logiciel dédié à la gestion de l'en... Cliquez pour télécharger Bureau de Gestion - ERP Devis Facturation 4Videosoft Transfert iPod Mac (3.2.08)4VIDEOSOFT TRANSFERT IPOD MAC (3.2.08)4Videosoft Transfert iPod-Mac caractérise principalement à transférer les fichiers iPod vers Mac.... Cliquez pour télécharger 4Videosoft Transfert iPod Mac 4Videosoft HD Convertisseur (3.3.08)4VIDEOSOFT HD CONVERTISSEUR (3.3.08)Etant le meilleur HD Vidéo Convertisseur, 4Videosoft HD Convertisseur, vous pouvez regarder la vi... Cliquez pour télécharger 4Videosoft HD Convertisseur
|