Denkfehler beim Deserialisieren eines UDT-Arrays

01/03/2013 - 12:12 von Wolfgang Wolf | Report spam
Hallo NG,

ich mache irgendwo einen Fehler und komme nicht darauf wo:

habe ein UDT:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dst
As Any, src As Any, ByVal bcount As Long)

Public Const MAXLENGTH_DESIGNATION = 30
Public Const MAXLENGTH_KEY = 12

Public Type tUDT
id As Long
typ As Long
d1 As Date
d2 As Date
d3 As Date
key As String * MAXLENGTH_KEY
Designation As String * MAXLENGTH_DESIGNATION
End Type


und folgende Proc:

Private Sub readData(m as string)
Dim b() As Byte
Dim u As tUDT
Dim i As Long, bSize As Long
Dim d As cData
Set d = data(m) 'Datenobjekt aus einer collection
b = d.GetData 'Liefert ein Byte-Array
bSize = LenB(u) 'Größe des UDTs ermitteln
Do While i < UBound(b)
CopyMemory u, b(i), bSize 'aus Array in UDT kopieren
i = i + bSize 'Zeiger neu setzen
'tue was mit u
Loop
End Sub

in den UDT's erhalte ich die Daten wie erwartet. Vermutlich aber
zerschieße ich irgendwas im lokalen Speicher weil d, also mein
Datenobjekt nach dem CopyMemory verloren geht (nothing wird).

Schönen Gruß
W. Wolf
 

Lesen sie die antworten

#1 Schmidt
04/03/2013 - 14:25 | Warnen spam
Am 01.03.2013 12:12, schrieb Wolfgang Wolf:

Private Sub readData(m as string)
Dim b() As Byte
Dim u As tUDT
Dim i As Long, bSize As Long
Dim d As cData
Set d = data(m) 'Datenobjekt aus einer collection
b = d.GetData 'Liefert ein Byte-Array
bSize = LenB(u) 'Größe des UDTs ermitteln
Do While i < UBound(b)
CopyMemory u, b(i), bSize 'aus Array in UDT kopieren
i = i + bSize 'Zeiger neu setzen
'tue was mit u
Loop
End Sub

in den UDT's erhalte ich die Daten wie erwartet. Vermutlich aber
zerschieße ich irgendwas im lokalen Speicher weil d, also mein
Datenobjekt nach dem CopyMemory verloren geht (nothing wird).



b = d.GetData 'Liefert ein Byte-Array

Hier müsstest Du (so wie der nachfolgende Loop implementiert ist)
innerhalb von GetData sicherstellen, dass b() immer genau multiple
LenB(u) Anzahl an Bytes enthàlt (also in Deinem Falle eine Gesamt-
Lànge von Bytes in b(), die ohne Rest durch 116 teilbar ist).

Mal angenommen, b() enthàlt nicht 232 Bytes (also zwei komplette
udts), sondern nur 200 Bytes (einen vollstàndigen udt - und noch
einen Rest):

Do While i < UBound(b)
CopyMemory u, b(i), bSize 'aus Array in UDT kopieren
i = i + bSize 'Zeiger neu setzen
'tue was mit u
Loop

Dann wàre im ersten Durchlauf des Loops noch alles gut.
Im zweiten Durchlauf steht i auf 116 (ist also korrekt
um die Lànge des udt inkrementiert) - aber der CopyMemory-
call:
CopyMemory u, b(116), bSize
versucht dann dann ausgehend vom Offset b(116) heraus
auf Arbeitsspeicherbereiche zuzugreifen, die so überhaupt
nicht in B alloziert sind (B enthàlt ja nur 200Bytes in
dem gegebenen Beispiel).

Das vielleicht nochmal àndern oder anpassen (entweder im
Loop selbst, oder in der GetData-Funktion die die Lànge des
Byte-Arrays auf "genaue Multiples" von Lenb(udt) checken könnte).

Olaf

Ähnliche fragen