begin process at 2012 02 04 12:43:55
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Visual Basic 6

 > 

Système

 > 

Mémoire

 > 

CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

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

Membre Club Administrateur CodeS-SourceS
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.


Ma signature pour pointer sur mon site
mardi 30 juin 2009 à 16:28:38 | Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

Renfield

Administrateur CodeS-SourceS
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

Membre Club Administrateur CodeS-SourceS
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.

Ma signature pour pointer sur mon site
mardi 30 juin 2009 à 17:04:13 | Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

Renfield

Administrateur CodeS-SourceS
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

Membre Club Administrateur CodeS-SourceS
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).

Ma signature pour pointer sur mon site
mardi 30 juin 2009 à 22:04:00 | Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

NHenry

Membre Club Administrateur CodeS-SourceS
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.

Ma signature pour pointer sur mon site
mercredi 1 juillet 2009 à 07:44:36 | Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

Renfield

Administrateur CodeS-SourceS
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

Membre Club Administrateur CodeS-SourceS
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.

Ma signature pour pointer sur mon site
mercredi 1 juillet 2009 à 09:35:38 | Re : CopyMemory, Len, LenB et la structure, comment tout faire fonctionner ?

Renfield

Administrateur CodeS-SourceS
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

Membre Club Administrateur CodeS-SourceS
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.

Ma signature pour pointer sur mon site

1 2

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 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 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 PB proprieté du type structure [ par mavrick2b ] Bonjour,J'ai crée une proprieté dans une classe qui a pour type une tructure, mais il m'est impossible de d'acceder à l'interieur de la structure par [VB.NET]Comment inclure une console DOS dans WinApplication? [ par PolluxMsts ] Bonjour à tous,Je recherche le moyen d'inclure une console DOS dans une application VB.Net 1.Par exemple :Le textbox affiche une application DOS.J' reupération données dans classeur fermer [ par souk69 ] Bonjour, j'ai un ti probleme qui est le suivant...Alors je sohaite recuperer des données dans un classeur fermé et j'ai taper le code ci dessous, le p Requête SQL sur plusieurs champs en même temps [ par acecel ] Bonjour  Je pense que le titre est assez explicite. Je travaille sous vb6 et access. J'aimerais pouvoir effectuer une requete sur plusieurs champs, je structure en VBA [ par borgeomi ] borgeomibonjouuuuuuur !!!!!Est-ce que sous EXCEL en VBA on peut employer des structures du typeType enreg_client    client_code_enregistrement    As S visualisation de structures de données sur un fichier [ par hela_bouks ] Salut, la dernière fois ou j'ai posé mon problème, les réponses que j'ai reçues m'ont vraiment super aidées, c'est pour cela que je retente ma chance. Comment ne pas tenir compte des accents ? [ par Alongra ] Bonjour tout le monde ! Voilà, sous Excel je dois comparer deux cellules, mais je suis confronté au problème des accents. Pour mon programme, Toto Béd


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,591 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales