Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Stream Lesefunktion aus XE7 funktioniert unter D2010 nicht korrekt (https://www.delphipraxis.net/200692-stream-lesefunktion-aus-xe7-funktioniert-unter-d2010-nicht-korrekt.html)

skoschke 16. Mai 2019 13:00

Stream Lesefunktion aus XE7 funktioniert unter D2010 nicht korrekt
 
Hallo,

ich komme nicht weiter, folgende Funktion (Auszug) lädt falsche Dateiinhalte bei Verwendung in D2010, unter XE7 ist es korrekt:

Delphi-Quellcode:
 
  ...
  Stream.ReadBuffer(loadcount, SizeOf(Integer)); //das sind 4 Bytes
  For i := 1 to loadcount do
  begin
    FillChar(AFieldRec, SizeOf(AFieldRec), #0);
    Stream.ReadBuffer(AFieldRec.Flags, SizeOf(LongWord)); //das sind 4 Bytes, im Original ist es DWord
    Stream.ReadBuffer(AFieldRec.Pos, SizeOf(TRect)); //16 Bytes
    if FRMVersion < 110 then
      Stream.ReadBuffer(AFieldRec.Typ, 1)
    else
      Stream.ReadBuffer(AFieldRec.Typ, SizeOf(TFieldTyp)); //2 Byte
    if AFieldRec.Typ = ft_Static then
    begin
      AFieldRec.UseTextH := true;
      Stream.ReadBuffer(TextSize, SizeOf(Integer)); //4 Bytes
      AFieldRec.TextH := GlobalAlloc(GMEM_FIXED, TextSize);
      Stream.ReadBuffer(GlobalLock(AFieldRec.TextH)^, TextSize);
    end
    else
    begin
      Stream.ReadBuffer(AFieldRec.FontSize, SizeOf(Integer)); //4 Bytes
      Stream.ReadBuffer(AFieldRec.FontAttr, SizeOf(Integer)); //4 Bytes
      Stream.ReadBuffer(AFieldRec.TextAlign, SizeOf(Integer)); //4 Bytes
      Stream.ReadBuffer(AFieldRec.TextColor, SizeOf(Integer)); //4 Bytes
      Stream.ReadBuffer(TextSize, SizeOf(Integer)); //4 Bytes
      SetLength(AFieldRec.FontName, TextSize);
      Stream.ReadBuffer(Pointer(AFieldRec.FontName)^, TextSize); //ist als TTXString deklariert
    end;
    end;
    ...
Ich habe mal meine Anzahl Bytes dahinterkommentiert.
Hat jemand eine Idee anhand des Codeschnipsels, was da schiefläuft?
Vermutung:

Delphi-Quellcode:
type
  TTXString = AnsiString;

   AFieldRec.FontName :TTXString;
Bin über jede Idde dankbar!

Ciao
Stefan

hoika 16. Mai 2019 13:11

AW: Stream Lesefunktion aus XE7 funktioniert unter D2010 nicht korrekt
 
Hallo,
die Byte-Ausrichtung in Records hatte sich doch mal geändert.
Teste mal mit SizeOf, ob beide die gleiche Größe haben.

Du verheimlichst uns leider AFieldRec.

Wenn Du beide Delphis am Laufen hast,
poste doch mal den genauen (ersten) Unterschied.

skoschke 16. Mai 2019 13:19

AW: Stream Lesefunktion aus XE7 funktioniert unter D2010 nicht korrekt
 
AFieldRec ist ein
Delphi-Quellcode:
type
  TNewFieldRec = record
    Typ: TFieldTyp;
    Page: Integer;
    Pos: TRect;
    UseTextH: Boolean;
    TextH: THandle;
    Text: TTXString;
    TextColor: TColor;
    Flags: LongWord;
    Zoom: Integer;
    FontName:TTXString;
    FontSize: Integer;
    FontAttr: Integer;
    TextAlign: Integer;
    TXFrame: TTXFrame;
    ParentWnd: HWnd;
    AddValue: Integer;
    WndID: LongWord;
    MaxChars: Integer;
    IndexPos: Integer;
  end;
und der TTXFrame ist
Delphi-Quellcode:
type
  TTXFrame = record
    State: LongWord;
    case Integer of
      0:
        (Sizes: LongWord);
      1:
        (LineWidth: Word;
          FrameDist: Word);
  end;
Wobei ich meine, dass der Recordaufbau unerheblich ist, denn es werden ja immer einzelne Record-Inhalte geladen?

Ciao
Stefan

hoika 16. Mai 2019 13:52

AW: Stream Lesefunktion aus XE7 funktioniert unter D2010 nicht korrekt
 
Hallo,
Zitat:

Wobei ich meine, dass der Recordaufbau unerheblich ist, denn es werden ja immer einzelne Record-Inhalte geladen?
fast.

Stream.ReadBuffer(AFieldRec.Typ, SizeOf(TFieldTyp)); //2 Byte

Das ReadBuffers schaltet ja Stream.Position um x Bytes weiter.
wenn TFieldType unter D2010 z.B. 3 Byte groß ist -> Puff

Ist SizeOf(TFieldTyp) bei beiden Delphis gleich?

PS:
TFieldTyp hat Du immer "unterschlagen" ;)


SetLength(AFieldRec.FontName, TextSize);
Hier könnte es sein, dass Du die Größe von AFieldRec aus Versehen änderst, musst du prüfen.

Ausserdem würde ich mal AnsiString durch ShortString ersetzen.


Um besten debuggst Du beide Delphis einfach mal parallel.

skoschke 16. Mai 2019 14:08

AW: Stream Lesefunktion aus XE7 funktioniert unter D2010 nicht korrekt
 
Darauf habe ich gewartet :-)
Ich habe nur D2010 und muss irgendwie den Code, der in XE7 entstand, zum Laufen bringen...

TFieldType ist 2 Bytes und im Stream auch an der richtigen Stelle zu finden.

SetLength(AFieldRec.FontName, TextSize); könnte die Größe verändern, sehe ich mir an...

Zitat:

Ausserdem würde ich mal AnsiString durch ShortString ersetzen.
Dann knallt es bei
Stream.ReadBuffer(Pointer(AFieldRec.FontName)^, TextSize);

Irgendwie ist mir diese Zeile unsympatisch...

Nachtrag:
Im Hexeditor kann man erkennen, dass diese Zeile 19 Zeichen zu viel liest...

Ciao
Stefan

hoika 16. Mai 2019 16:21

AW: Stream Lesefunktion aus XE7 funktioniert unter D2010 nicht korrekt
 
Hallo,
Zitat:

Ich habe nur D2010
Die Community-Edition kann viell. helfen.

Zitat:

Stream.ReadBuffer(Pointer(AFieldRec.FontName)^, TextSize); //ist als TTXString deklariert
Das hatte ich gar nicht gesehen.
Au weia !!!

vielleicht
Stream.ReadBuffer(PAnsiChar(AFieldRec.FontName), TextSize);

oder mit GetMem/FreeMem/StrPCopy arbeiten


Wie gross ist denn TextSize?

peterbelow 16. Mai 2019 17:46

AW: Stream Lesefunktion aus XE7 funktioniert unter D2010 nicht korrekt
 
Zitat:

Zitat von skoschke (Beitrag 1432342)
Stream.ReadBuffer(Pointer(AFieldRec.FontName)^, TextSize); //ist als TTXString deklariert

Irgendwie ist mir diese Zeile unsympatisch...

Nachtrag:
Im Hexeditor kann man erkennen, dass diese Zeile 19 Zeichen zu viel liest...

Ciao
Stefan

Hat Textsize den richtigen Wert?

Anyway, ersetzte diese Zeile mal durch

Stream.ReadBuffer(AFieldRec.FontName[1], TextSize);

Da der erste Parameter von ReadBuffer ein untyped Var ist übergibt das die Addresse des ersten Zeichens der Fontname-Variablen, das sollte passen.

skoschke 17. Mai 2019 07:04

AW: Stream Lesefunktion aus XE7 funktioniert unter D2010 nicht korrekt
 
So, wollte mal Rückmeldung geben:

Zitat:

Stream.ReadBuffer(AFieldRec.FontName[1], TextSize);
gefällt mir viiiieeeel besser, irgendwie war das Pointer-Handling für mich undurchsichtig...

Grund für die falsch gelesenen Inhalte war aber ein ganz anderer:
Da ist bei der Übernahme des Codes von XE7 glatt eine Zeile verloren gegangen:
Delphi-Quellcode:
      Stream.ReadBuffer(AFieldRec.TextColor, SizeOf(Integer));
      Stream.ReadBuffer(AFieldRec.TXFrame,SizeOf(TTXFrame)); <------- die fehlte
      Stream.ReadBuffer(TextSize, SizeOf(Integer));
      SetLength(AFieldRec.FontName, TextSize);
      Stream.ReadBuffer(Pointer(AFieldRec.FontName)^, TextSize);
und damit hat alles nachfolgende natürlich Murks gelesen!

Danke für Eure Unterstützung.

Ciao
Stefan


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz