sandiego
sandiego

Reputation: 161

Variable Required error with TStream.Write()

I am trying to compile a project but I guess this error "Variable Required"

function ReadInteger(SomeTStream:TStream):integer;
  begin
    SomeTStream.Read(Result, SizeOf(Result));
  end;

Top:=ReadInteger(SomeTStream);
Left:=ReadInteger(SomeTStream);
Height:=ReadInteger(SomeTStream);
Width:=ReadInteger(SomeTStream);

Then when it tries to write it stops in Top and Left.

SomeTStream.Write(Top,SizeOf(Top));
                    ^
SomeTStream.Write(Left,SizeOf(Top));}
                     ^
E2036 Variable required

I read about the problem in here

But still I have no idea what should I do to fix it.

Upvotes: 0

Views: 975

Answers (1)

David Heffernan
David Heffernan

Reputation: 613013

It's exactly as the error says. The parameter must be a variable. But you are passing a property that is implemented using a getter function. Copy the property into a variable and pass that to the function.

var
  Value: Integer;
....
Value := Top;
Stream.Write(Value, SizeOf(Value));

Some helper methods would be most useful here to avoid drowning in boiler-plate. In fact you already added one for ReadInteger and you just need a matching one for WriteInteger.

procedure WriteInteger(Stream: TStream; Value: Integer);
begin
  Stream.Write(Value, SizeOf(Value));
end;

What's going on here is that the Write method of TStream is declared like so:

function Write(const Buffer; Count: Longint): Longint; virtual; abstract;

Because this function receives an untyped parameter, it cannot be passed by value. The address of the parameter is actually passed, and so the caller needs to supply something with an address. Your property does not fit the bill.


Incidentally, usually, Write and Read are the wrong methods to call on TStream. They do not perform any error checking. They leave that to you. The Write and Read are abstract methods that are used by specialized classes to provide the stream implementation. You are generally expected to call WriteBuffer and ReadBuffer.


Or perhaps a binary writer would help.

var
  bw: TBinaryWriter;
....
bw := TBinaryWriter.Create(Stream);
try
  bw.Write(Top);
  bw.Write(Left);
  // etc.
finally
  bw.Free;
end;

Upvotes: 3

Related Questions