Link to home
Start Free TrialLog in
Avatar of Saxon
Saxon

asked on

read from TMemoryStream fails

I want to use a stream for example for clipboard operations. If I read and write the stream within the same procedure (Button3Click) it occures successfull. If I split this procedure into the Button1Click+Button2Click procedures I loose in the line marked as {B} the value of RecordDestination.Wort. This value has been modified in a mysterious way at this point.
Up to now I have no expirience using streams. May be I'm wrong but I think it should be possible to to use streams in this way.


type
      TMyRecord = record
            Zahl: cardinal;
            Wort: String;
      end;

var
      Form1: TForm1;
      MyStream: TMemoryStream;

implementation

procedure TForm1.Button1Click(Sender: TObject);
var
      RecordSource: TMyRecord;
begin
  RecordSource.Zahl:=123;
  RecordSource.Wort:='BullShit';
    MyStream:=TMemoryStream.Create;
    MyStream.Clear;
    MyStream.Write(RecordSource,SizeOf(RecordSource));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
      RecordDestination: TMyRecord;
begin
      MyStream.Seek(0,soFromBeginning);
      MyStream.Read(RecordDestination,MyStream.Size);
      MyStream.Free;
{A}   Edit5.Text:=IntToStr(RecordDestination.Zahl);
      Edit6.Text:=RecordDestination.Wort;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
      RecordSource, RecordDestination: TMyRecord;
begin
  RecordSource.Zahl:=124;
  RecordSource.Wort:='Bulleye';
    MyStream:=TMemoryStream.Create;
    MyStream.Clear;
    MyStream.Write(RecordSource,SizeOf(RecordSource));
      MyStream.Seek(0,soFromBeginning);
      MyStream.Read(RecordDestination,MyStream.Size);
      MyStream.Free;
{B}   Edit5.Text:=IntToStr(RecordDestination.Zahl);
      Edit6.Text:=RecordDestination.Wort;
end;
Avatar of inter
inter
Flag of Türkiye image

My dear friend,
you can not simply read and write the records containing pointers or dynamic  strings:
instead you may change the record in to
TMyRecord = record
    Zahl: cardinal;
    Wort: ShortString;
end;
and try again,
regards, igor
Avatar of Madshi
Madshi

Saxon,

igor is right.
the type "string" is kind of (not exactly) a pointer to an array of char. That means your record is only 8 bytes long. If you use igor's variant then your record will be 4+256 bytes long, since the characters of your string are then really stored in your record.
If 256 bytes are not enough for you respectively if you want dynamic string because of some other reasons you can save your use the following code:

procedure TForm1.Button1Click(Sender: TObject);
var RecordSource : TMyRecord;
    i1           : integer;
begin
  RecordSource.Zahl:=123; RecordSource.Wort:='BullShit';
  MyStream:=TMemoryStream.Create; // you don't need to clear it...
  try
    // writing:
    MyStream.Write(RecordSource.Zahl,sizeOf(cardinal));
    i1:=length(RecordSource.Wort);
    MyStream.Write(i1,sizeOf(integer));
    MyStream.Write(PChar(RecordSource.Wort)^,i1);
    // reading:
    MyStream.position:=0;
    MyStream.Read(RecordSource.Zahl,sizeOf(cardinal));
    MyStream.Read(i1,sizeOf(integer));
    SetLength(RecordSource.Wort,i1);
    MyStream.Read(PChar(RecordSource.Wort)^,i1);
  finally MyStream.Free end;
end;

Regards, Madshi.

P.S: Schöne Grüße...
Avatar of Saxon

ASKER

Great, it works, but please explain me at last, why it works in the other case (and sometime - I tried different other versions - in the splitted manner too).
Because you saved the pointer to the string and reloaded it. So if the record (and the string) still exists the loaded pointer is still correct.
Which way do you want to use? Igor's or mine?
Avatar of Saxon

ASKER

Thx, for your string->widestring->string hint too!
For the moment I'll use Igor's way, but the points I'd like to give to you. Your answer was more helpful for my understanding. Hope Igor agrees, thanks to you too!
Lutz
Sure man,
please answer Madshi,
igor
ASKER CERTIFIED SOLUTION
Avatar of Madshi
Madshi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
nothing specific friend, is just a SHIFT saving...
regards, igor (or may be I am a poet like Cummings)
Igor,

ok, you can call me "madshi" to save another shift...   :-)

Regards, Madshi.
nothing specific friend, is just a SHIFT saving...
regards, igor (or may be I am a poet like Cummings)
ok madshi ;-) sorry for reposting...