[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2523
  • Last Modified:

how to use dynamic array in packed record like fixed array?

Hi,I have a packed record here:

=========================
tagCngpTLV = packed record
    Tag:WORD;
    Length:WORD;
    Value:Array of Byte;
    Reserve:Array[0..7] of Byte;
end;
=========================
I have an record like this:
CngpTLV1:tagCngpTLV
Tag:$0001,
Length:$0006;
Value:$FF,FF,FF,FC,00,00
Reserve:$00,00,00,00,00,00,00,00

if I use CngpTLV1 as a buffer to insert it into a stream,the data in Value postion became a ^Array pointer.
How Can I use it like an
    Tag:WORD;
    Length:WORD;
    Value:Array[0..5] of Byte;
    Reserve:Array[0..7] of Byte;
record?

in fact I have more complex record struct so I can't use another buffer and calc the each items' postion&size then copy into it one by one.
0
azsd
Asked:
azsd
  • 2
2 Solutions
 
robert_marquardtCommented:
You cannot use "array of" in this way. Value is in fact nothing but a pointer.
You have to use SetLength() to allocate memory on the heap before using Value.
So you cannot read the record in a single read operation. Read Tag and Length and then call SetLength(Rec.Value, Rec.Length).
Now you can read Rec.Value, followed by reading Reserve.
0
 
esoftbgCommented:
I had no problems this way:

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  CngpTLV1.Tag := $0001;
  CngpTLV1.Length := $0006;
  SetLength(CngpTLV1.Value, 6);
  CngpTLV1.Value[0] := $FF;
  CngpTLV1.Value[1] := $FF;
  CngpTLV1.Value[2] := $FF;
  CngpTLV1.Value[3] := $FC;
  CngpTLV1.Value[4] := $00;
  CngpTLV1.Value[5] := $00;
  CngpTLV1.Reserve[0] := $00;
  CngpTLV1.Reserve[1] := $00;
  CngpTLV1.Reserve[2] := $00;
  CngpTLV1.Reserve[3] := $00;
  CngpTLV1.Reserve[4] := $00;
  CngpTLV1.Reserve[5] := $00;
  CngpTLV1.Reserve[6] := $00;
  CngpTLV1.Reserve[7] := $00;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  SetLength(CngpTLV1.Value, 0);
end;
0
 
azsdAuthor Commented:
sorry,I haven't describe my problem clearly.

I have aready alloced 6 byte Value by setlength and Move()-ed some datas in record,
I wan't to get an datastream like this for use:

$01,00;$06,00;$FF,FF,FF,FC,00,00;$00,00,00,00,00,00,00,00

and now I use the @CngpTLV1 as an buffer pointer,
the data in memory like

$01,00;$06,00;$28,00,60,00;$00,00,00,00,00,00,00,00

I had to use code like:
var
  newbuf:array of byte;
begin
  //CngpTLV1 ready
  SetLength(newbuf,sizeof(CngpTLV1)-Sizeof(CngpTLV1.value)+CngpTLV1.Length);
  FillChar(newbuf,Length(newbuf),0);
  Move(CngpTLV1,newbuf[0],sizeof(CngpTLV1.Tag)+Sizeof(CngpTLV1.Length));
  Move(CngpTLV1.Value[0],newbuf[sizeof(CngpTLV1.Tag)+Sizeof(CngpTLV1.Length)],CngpTLV1.Length);
  Move(CngpTLV1.Reserve,newbuf[sizeof(CngpTLV1.Tag)+Sizeof(CngpTLV1.Length)+CngpTLV1.Length],sizeof(CngpTLV1.Reserve));
  //Send(clientsocket, newbuf[0],Length(newbuf),0);
  //or save the buf to disk
end;

In reality application,there some more then 40 member record with about 6,7 dynamic length,
I want to kick my screen usually.

I tried to use follow codes:

    Tag:WORD;
    Length:WORD;
    Value:Array[0..Length-1] of Byte;
    Reserve:Array[0..7] of Byte;

sure I was shamely get grammer error.
0
 
azsdAuthor Commented:
quote:
I want to get an datastream like this for use,not "wan't"
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now