Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi SetString aus dyn. Array (https://www.delphipraxis.net/146870-setstring-aus-dyn-array.html)

sundance 28. Jan 2010 12:38


SetString aus dyn. Array
 
Hallo,

ich komme hier einfach nicht weiter...
Ich bin sicher, ihr könnt mir da helfen:

Ich habe ein dynamisches Array of Byte (Data), in dem im aktuellen Fall an Position Data[0] $00 steht, auf den folgenden Positionen stehen AnsiChar. Mein Plan war, diese Zeichen mit SetString() in eine AnsiString-Var zu kopieren:
Delphi-Quellcode:
...
type
  TBuffer = Array of Byte;
var
  Data: TBuffer;
  st: AnsiString;
  len: Integer;
begin
  (Stream.Read füllt das Array mit Daten; ist mit SetLength initialisiert)
  header := Data[0];
  len := Length(Data) - 1;
  SetString(st, Data[1], len);         -> Incompatible types (OK)
  SetString(st, PChar(@Data[0]), len); -> kompiliert, liefert aber natürlich falsche Daten
  SetString(st, PChar(@Data[1]), len); -> EAccessViolation (?)
end;
...
Das Problem liegt an der Übergabe der Source von SetString.
Was ist hier falsch? Wenn ich das richtig verstehe, ist "Data" ja der Zeiger auf das dyn. Array; Data[1] zeigt auf das zweite Zeichen im Array und SetString will einen PChar auf die Startadresse...

.sundance.

mkinzler 28. Jan 2010 13:24

Re: SetString aus dyn. Array
 
Dynamische Arrays muss man dimensionieren (SetLength())

gammatester 28. Jan 2010 13:35

Re: SetString aus dyn. Array
 
Neben dem was, mkinzler gesagt hat, gibt es ein Mischmasch aus Type/var-Deklaration, die nicht übersetzt wird. Entweder type data = oder var data: aber nicht type Data: Array of Byte. Jedenfalls funktioniert der folgende Schnipsel ohnt Probleme:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Data : Array of Byte;
var
  st: AnsiString;
  len: Integer;
begin
  setlength(data,4);
  data[0] := 0;
  data[1] := $31;
  data[2] := $32;
  data[3] := $33;
  len := Length(Data) - 1;
  SetString(st, PChar(@Data[1]), len);
  button1.Caption := st;
end;

sundance 28. Jan 2010 14:08

Re: SetString aus dyn. Array
 
@mkinzler:
Selbstverständlich wurde das array mit SetLength() dimensioniert; habe ich vielleicht etwas missverständlich im Quelltextschnippsel kommentiert...

@gammatester:
Du hast natürlich recht, das mit dem Type ist Quatsch (ich habe das hier nur schnell eingetippt, nicht per copy-paste aus meinem Quelltext übernommen; ich wollte nur das Wesentliche darstellen).
So wie dein Code aussieht, hätte ich mir auch vorgestellt, dass es funktionieren müßte. Warum ich in meinem Falle eine Access-Violation bekomme, ist mir noch nicht ganz klar. Das Array ist auf jeden Fall korrekt dimensioniert, sonst würde schon der Stream.Read() fehlschlagen. Oder stimmt hier vielleicht etwas nicht:
Delphi-Quellcode:
var
  DData: array of Byte;        // dyn. Array
  SData: array[0..255] of Byte; // stat. Array
begin
  dataSize := GetDataSize(...);
  SetLength(DData, dataSize);
  srcFile.Read(DData[0], dataSize); // hier muß doch auch "dereferenziert" werden, wg. dyn. Array?
  srcFile.Read(SData, dataSize);    // hier nicht...
end;

gammatester 28. Jan 2010 14:32

Re: SetString aus dyn. Array
 
Das dürfte krachen, wenn Du mehr als 255 Bytes nach SData lesen willst. Der dynamische Teil funktioniert bei mir:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Data : Array of Byte;
var
  st: AnsiString;
  len: Integer;
  f: tfilestream;
begin
  f := tfilestream.Create('test',fmOpenRead);
  try
    setlength(data,f.size);
    f.Read(data[0],f.size);
  finally
    f.Free;
  end;
  len := Length(Data) - 1;
  SetString(st, PChar(@Data[1]), len);
  button1.Caption := st;
end;

sundance 28. Jan 2010 15:25

Re: SetString aus dyn. Array
 
Hallo gammatester,

vielen Dank für deinen Einsatz; jetzt funktioniert's in meiner Funktion auch.
Und es hatte auch nichts mit dem dynamischen Array und dessen Adressierung zu tun, sondern war ein echt blöder Programmierfehler... :roll:
(mein Fehler-Quelltext war etwas länger (hier gekürzt) und irgendwann zwischen Stream.Read und SetString wurde eine Variable versehentlich überschrieben... (mea culpa!)

.sundance.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:40 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