Board index » delphi » ???Please Help, passing Dynamic Array???

???Please Help, passing Dynamic Array???

Hi there, does anybody knows how to pass a dynamic array between server
and client, i always get an access violation. I know that it has
something to do with the size of the VarArray which i define at runtime
on the server side and is undefined at the client side. The only way
that i can pass an array is defining it as static on both side, example
Array[1..1000] of Integer.  I have the same problem trying to pass
Strings (unknown length), i have to define every string variable as
static String[50] for example.

If anybody can help me understand what i'm doing wrong and how to share
between server and client dynamic variables i will be very grateful

***** The code that i'm using at the server side is: *************

Function.ServerSIDE(Count:Integer;spConnect:TDataset): OleVariant;
TSegOBJ = Record
   ObjetoID:Smallint;
   Nombre:String[60];
   TipoTB:String[2];
   Display:String[1];
   NivelNodo:Smallint;
   Nodo:String[25];
   ImgNum:Smallint;
   ImgAbrir:Smallint;
   ImgCerrar:Smallint;
   Seguridad:Smallint;
 End;
 TConnect = record
    Status:Smallint;
    Fecha:TDateTime;
    Mensaje:String[255];
    Count:Smallint;
 End;
 TToken = record
   Connect:TConnect;
   ArrOBJ:Array of TSegOBJ
 End;
 Var
    Data: Pointer;
    MyRecord: TToken;
 Begin

  SetLength(MyRecord.ArrOBJ,Count);
  MyRecord.Connect.Mensaje:='Connected';
   MyRecord.Connect.Fecha:=spConnect.ParamByName('@Fecha').asDateTime;
   spConnect.Close;
   spConnect.ParamByName('@Accion').asInteger:=2;
   spConnect.Open;
   SetLength(MyRecord.ArrOBJ,Count);
   Count:=0;
   While Not spConnect.EOF Do
        Begin
          MyRecord.ArrOBJ[Count].ObjetoID:=spConnect.Fields[0].Value;
          MyRecord.ArrOBJ[Count].Nombre:=spConnect.Fields[1].Value;
          MyRecord.ArrOBJ[Count].TipoTB:=spConnect.Fields[2].Value;
          MyRecord.ArrOBJ[Count].Display:=spConnect.Fields[3].Value;
          MyRecord.ArrOBJ[Count].NivelNodo:=spConnect.Fields[4].Value;
          MyRecord.ArrOBJ[Count].Nodo:=spConnect.Fields[5].Value;
          MyRecord.ArrOBJ[Count].ImgNum:=spConnect.Fields[6].Value;
          MyRecord.ArrOBJ[Count].ImgAbrir:=spConnect.Fields[7].Value;
          MyRecord.ArrOBJ[Count].ImgCerrar:=spConnect.Fields[8].Value;
          MyRecord.ArrOBJ[Count].Seguridad:=spConnect.Fields[9].Value;
          Inc(Count);
          spConnect.Next;
        End;
  spConnect.Close;
  Result:=  varArrayCreate([0,Sizeof(MyRecord)],VarByte);
  Data:= VarArrayLock(Result);
  CopyMemory(Data,@MyRecord,Sizeof(MyRecord));
  VarArrayUnLock(Result);
End;

***** The code that i'm using at the client side is: *************

procedure TfrmAcceso.btnAceptarClick(Sender: TObject);
TSegOBJ = Record
   ObjetoID:Smallint;
   Nombre:String[60];
   TipoTB:String[2];
   Display:String[1];
   NivelNodo:Smallint;
   Nodo:String[25];
   ImgNum:Smallint;
   ImgAbrir:Smallint;
   ImgCerrar:Smallint;
   Seguridad:Smallint;
 End;
 TConnect = record
    Status:Smallint;
    Fecha:TDateTime;
    Mensaje:String[255];
    Count:Smallint;
 End;
 TToken = record
   Connect:TConnect;
   ArrOBJ:Array of TSegOBJ
 End;

Var
   v:Variant;
   fToken:TToken;
   i:Integer;
   fMens:String;
begin
  fSckConnect.connected:=True;
  v:=fSckConnect.AppServer.Login(User.text,Password.Text);
  fToken := VarArrayLock(v);
  If fToken^.Connect.Status = 1 Then
    Begin
       fStatusBar.Panels[0].Text:='Estado: '+fToken^.Connect.Mensaje;
       fStatusBar.Panels[1].Text:='Usuario conectado: '+Usuario;
        ShowMessage(fToken^.ArrOBJ[9].Nombre); //*** Access Violation
****
    End
  Else
    Begin
      MessageDLG(fToken^.Connect.Mensaje,mtError,[mbOK],0);
      fConnected:=False;
      If fToken^.Connect.Status = 99 Then
      Begin
          Show;
          Exit;
      End;
    End;
  Close;
end;

 

Re:???Please Help, passing Dynamic Array???


In article <38B70F0C.3D12A...@chilesat.net>, Esteban Caldentey Morales
wrote:
Quote

<snip>
>  TToken = record
>    Connect:TConnect;
>    ArrOBJ:Array of TSegOBJ
>  End;
>  Var
>     Data: Pointer;
>     MyRecord: TToken;
>  Begin

<snip>
>   Result:=  varArrayCreate([0,Sizeof(MyRecord)],VarByte);
>   Data:= VarArrayLock(Result);
>   CopyMemory(Data,@MyRecord,Sizeof(MyRecord));
>   VarArrayUnLock(Result);
> End;

<snip>

I don't think SizeOf can give you the correct size of your TToken
record, because it contains an unknown (at compile time) number of
TSegOBJ records

Can you check what SizeOf(MyRecord) is actually returning in the
de{*word*81}? Assuming it's wrong, I think what you actually need to do is
something like this:

RunTimeSizeOfMyRecord := SizeOf(TConnect) + Count * SizeOf(TSegOBJ);

Result := varArrayCreate([0, RunTimeSizeOfMyRecord - 1], VarByte);

and

CopyMemory(Data, @MyRecord, RunTimeSizeOfMyRecord);

I imagine you'll need to make similar adjustments on the client side as
well.

Roger Morton
roger.mor...@dial.pipex.com

Re:???Please Help, passing Dynamic Array???


Thank Roger, your are right.

Regards, Esteban.

Quote
Roger Morton wrote:
> In article <38B70F0C.3D12A...@chilesat.net>, Esteban Caldentey Morales
> wrote:

> <snip>
> >  TToken = record
> >    Connect:TConnect;
> >    ArrOBJ:Array of TSegOBJ
> >  End;
> >  Var
> >     Data: Pointer;
> >     MyRecord: TToken;
> >  Begin

> <snip>
> >   Result:=  varArrayCreate([0,Sizeof(MyRecord)],VarByte);
> >   Data:= VarArrayLock(Result);
> >   CopyMemory(Data,@MyRecord,Sizeof(MyRecord));
> >   VarArrayUnLock(Result);
> > End;
> <snip>

> I don't think SizeOf can give you the correct size of your TToken
> record, because it contains an unknown (at compile time) number of
> TSegOBJ records

> Can you check what SizeOf(MyRecord) is actually returning in the
> de{*word*81}? Assuming it's wrong, I think what you actually need to do is
> something like this:

> RunTimeSizeOfMyRecord := SizeOf(TConnect) + Count * SizeOf(TSegOBJ);

> Result := varArrayCreate([0, RunTimeSizeOfMyRecord - 1], VarByte);

> and

> CopyMemory(Data, @MyRecord, RunTimeSizeOfMyRecord);

> I imagine you'll need to make similar adjustments on the client side as
> well.

> Roger Morton
> roger.mor...@dial.pipex.com

Other Threads