Solved

read from TMemoryStream fails

Posted on 1998-09-21
11
208 Views
Last Modified: 2010-04-06
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;
0
Comment
Question by:Saxon
  • 5
  • 4
  • 2
11 Comments
 
LVL 5

Expert Comment

by:inter
ID: 1340387
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
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1340388
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...
0
 

Author Comment

by:Saxon
ID: 1340389
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).
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 20

Expert Comment

by:Madshi
ID: 1340390
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?
0
 

Author Comment

by:Saxon
ID: 1340391
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
0
 
LVL 5

Expert Comment

by:inter
ID: 1340392
Sure man,
please answer Madshi,
igor
0
 
LVL 20

Accepted Solution

by:
Madshi earned 100 total points
ID: 1340393
Thanx Saxon, thanx igor...   :-)

P.S: igor, why do you call yourself "igor" instead of "Igor"?
0
 
LVL 5

Expert Comment

by:inter
ID: 1340394
nothing specific friend, is just a SHIFT saving...
regards, igor (or may be I am a poet like Cummings)
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1340395
Igor,

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

Regards, Madshi.
0
 
LVL 5

Expert Comment

by:inter
ID: 1340396
nothing specific friend, is just a SHIFT saving...
regards, igor (or may be I am a poet like Cummings)
0
 
LVL 5

Expert Comment

by:inter
ID: 1340397
ok madshi ;-) sorry for reposting...
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question