BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Passing a two dimensional array from client app to middle ti

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Databases (Multi-Tier)
View previous topic :: View next topic  
Author Message
RandChris
Guest





PostPosted: Thu Apr 01, 2004 10:38 pm    Post subject: Passing a two dimensional array from client app to middle ti Reply with quote



This technique is derived, as best as possible, from the article
http://community.borland.com/article/0,1410,25982,00.htm.
I get an arror from the server portion when attempting execute. The
point at which the error occurs is indicated in upper case notation.

Here is some sample code using the techniques that are in your example.
I am passing an array from a client to a middle layer for further
processing. at the very in, I'll a message 'the server threw an
exception'. If you can help me resolve this I will appreciate it very much.

Please note rfWhereFilter and ParamArray are an array[0..1] of string

{ server code}
procedure TGenRptEngine.AssignWhereFilter(vData: OleVariant);
var
aFilterString : Array of ParamArray ;
pData : PByteArray;

begin

setlength( aFilterString,1);

pData := VarArrayLock( vData ) ;
try

Move( pData^, AFilterString, SizeOf( aFilterString )) ;

finally
VarArrayUnLock( vData ) ;
end;
THE CODE APPEARS TO WORK FINE DOWN TO THIS POINT AS I TESTED IT WITH
MESSAGE BOXES.
ANY ATTEMPT TO ACCESS AN ARRAY ELEMENT WILL GENERATE AN EXCEPTION.
Form1.AssignSelectFilters( aFilterString );

end;
{ END OF SERVER CODE}
{ CLIENT CODE }
procedure TForm1.Button2Click(Sender: TObject);
Var
AWhereFilter : Array of rfWhereFilter ;
VData : Variant;
PData : PByteArray;
begin
cdsFilterString.First ;
{ the data is loaded from a client dataset into an array and then an ole
variant. The client dataset is being temporarily as the final data will
be be read from the registry into an array}

while not cdsFilterString.Eof do begin
{if High( aWhereFilter ) = -1 then
SetLength( aWhereFilter, 1 )
else }
SetLength( aWhereFilter, Max( High(aWhereFilter ) + 1,1) ) ;
aWhereFilter[ High(aWhereFilter),0] := cdsFilterStringCompName.asString ;
aWhereFilter[ High(aWhereFilter),1] := cdsFilterStringCompValue.asString ;
cdsFilterString.Next ;
end;
if High( aWhereFilter ) > -1 then
VData := VarArrayCreate( [0, SizeOf( aWhereFilter ) - 1], varByte );
PData := VarArrayLock( vData ) ;
try
Move(aWhereFilter, PData^, SizeOf(aWhereFilter) ) ;
Finally
VarArrayUnLock( vData ) ;
end;
GenRptEngine.AssignWhereFilter( vData );

{END OF CLIENT CODE}

Back to top
Gürcan YÜCEL
Guest





PostPosted: Fri Apr 02, 2004 8:09 am    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote



I dont know the reason exactly but,
I was using array streams between client and server. I think it must be in
definite sizes. For this reason use STRING[100] instead STRING in array. I
dont know that array must be in specific size or not.

"RandChris" <RCoyle (AT) pfshouston (DOT) com> wrote

Quote:
This technique is derived, as best as possible, from the article
http://community.borland.com/article/0,1410,25982,00.htm.
I get an arror from the server portion when attempting execute. The
point at which the error occurs is indicated in upper case notation.

Here is some sample code using the techniques that are in your example.
I am passing an array from a client to a middle layer for further
processing. at the very in, I'll a message 'the server threw an
exception'. If you can help me resolve this I will appreciate it very
much.

Please note rfWhereFilter and ParamArray are an array[0..1] of string

{ server code}
procedure TGenRptEngine.AssignWhereFilter(vData: OleVariant);
var
aFilterString : Array of ParamArray ;
pData : PByteArray;

begin

setlength( aFilterString,1);

pData := VarArrayLock( vData ) ;
try

Move( pData^, AFilterString, SizeOf( aFilterString )) ;

finally
VarArrayUnLock( vData ) ;
end;
THE CODE APPEARS TO WORK FINE DOWN TO THIS POINT AS I TESTED IT WITH
MESSAGE BOXES.
ANY ATTEMPT TO ACCESS AN ARRAY ELEMENT WILL GENERATE AN EXCEPTION.
Form1.AssignSelectFilters( aFilterString );

end;
{ END OF SERVER CODE}
{ CLIENT CODE }
procedure TForm1.Button2Click(Sender: TObject);
Var
AWhereFilter : Array of rfWhereFilter ;
VData : Variant;
PData : PByteArray;
begin
cdsFilterString.First ;
{ the data is loaded from a client dataset into an array and then an ole
variant. The client dataset is being temporarily as the final data will
be be read from the registry into an array}

while not cdsFilterString.Eof do begin
{if High( aWhereFilter ) = -1 then
SetLength( aWhereFilter, 1 )
else }
SetLength( aWhereFilter, Max( High(aWhereFilter ) + 1,1) ) ;
aWhereFilter[ High(aWhereFilter),0] := cdsFilterStringCompName.asString ;
aWhereFilter[ High(aWhereFilter),1] := cdsFilterStringCompValue.asString ;
cdsFilterString.Next ;
end;
if High( aWhereFilter ) > -1 then
VData := VarArrayCreate( [0, SizeOf( aWhereFilter ) - 1], varByte );
PData := VarArrayLock( vData ) ;
try
Move(aWhereFilter, PData^, SizeOf(aWhereFilter) ) ;
Finally
VarArrayUnLock( vData ) ;
end;
GenRptEngine.AssignWhereFilter( vData );

{END OF CLIENT CODE}




Back to top
David M
Guest





PostPosted: Fri Apr 02, 2004 9:18 am    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote



On Fri, 2 Apr 2004 11:09:50 +0300, "Gürcan YÜCEL" <gyucel (AT) g-gsoft (DOT) com>
wrote:

Quote:
I dont know the reason exactly but,
I was using array streams between client and server. I think it must be in
definite sizes. For this reason use STRING[100] instead STRING in array. I
dont know that array must be in specific size or not.


For use in multi tier applications pass strings using the Widestring
type. This corresponds to the BSTR IDL type which is a binary string.
Delphi strings are not automation compatible.

For more info see the Help file .

Regards

David M




Back to top
RandChris
Guest





PostPosted: Fri Apr 02, 2004 4:55 pm    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote

References: <406c99f9$1 (AT) newsgroups (DOT) borland.com> <406d1f7e (AT) newsgroups (DOT) borland.com> <mqbq60dtl3lj314magc0vm3q907muntr3e (AT) 4ax (DOT) com>
In-Reply-To: <mqbq60dtl3lj314magc0vm3q907muntr3e (AT) 4ax (DOT) com>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
NNTP-Posting-Host: 12.109.22.4
Message-ID: <406d9ae3$1 (AT) newsgroups (DOT) borland.com>
X-Trace: newsgroups.borland.com 1080924899 12.109.22.4 (2 Apr 2004 08:54:59 -0800)
Lines: 32
Path: number1.nntp.ash.giganews.com!internal1.nntp.ash.giganews.com!border2.nntp.ash.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
Xref: number1.nntp.ash.giganews.com borland.public.delphi.database.multi-tier:45761

I assumed from looking at the code that the array of strings were moved=20
into a variant array prior to being passed. Is this correct from the=20
example provided.

David M wrote:
Quote:
On Fri, 2 Apr 2004 11:09:50 +0300, "G=FCrcan Y=DCCEL" om
wrote:
=20
=20
I dont know the reason exactly but,
I was using array streams between client and server. I think it must be=
in
definite sizes. For this reason use STRING[100] instead STRING in array=
=2E I
dont know that array must be in specific size or not.
=20
=20
=20
For use in multi tier applications pass strings using the Widestring
type. This corresponds to the BSTR IDL type which is a binary string.
Delphi strings are not automation compatible.
=20
For more info see the Help file .
=20
Regards
=20
David M
=20
=20
=20


Back to top
Tony Blomfield
Guest





PostPosted: Fri Apr 02, 2004 7:20 pm    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote

Here is an working example straigh from a working project. Hope it helps.

Client Side:

procedure TDMCache.GetServerCacheCheckSumArray;
//Transfer the Array of Cache Checksums from the Appserver to the client as
a ByteStream
var
PData: PByteArray;
VData: Variant;
begin
FillChar(FServerMaxCacheIDs, SizeOf(FServerMaxCacheIDs), #0);
Appinfo.RemoteServer.Appserver.AS_GetCacheSumArray(VData);
PData := VarArrayLock(VData);
try
move(PData^, FServerMaxCacheIDs, SizeOf(FServerMaxCacheIDs));
finally
VarArrayUnlock(VData);
end;
end;


Server Side:


procedure TCIDG_RDM.AS_GetCacheSumArray(var CacheSumArray: OleVariant);
var
i : Integer;
TempArray : array[TCacheTableID] of Integer;
PData : PByteArray;
begin
// HelperObject.Logit(nil, 'AS_GetCacheSumArray', kProcedure);
DMCache.GetCacheSumArray(CacheSumArray);
PData:= VarArrayLock(CacheSumArray);
try
move(PData^, TempArray, Sizeof(TempArray));
for i:= 0 to length(FMaxOwnerLevelCacheIDs) - 1 do
begin
TempArray[TCacheTableID(i)]:= TempArray[TCacheTableID(i)] +
FMaxOwnerLevelCacheIDs[TCacheTableID(i)];
end;
move(TempArray, PData^, Sizeof(TempArray));
finally
VarArrayUnlock(CacheSumArray);
end;

end;









"RandChris" <RCoyle (AT) pfshouston (DOT) com> wrote

Quote:
This technique is derived, as best as possible, from the article
http://community.borland.com/article/0,1410,25982,00.htm.
I get an arror from the server portion when attempting execute. The
point at which the error occurs is indicated in upper case notation.

Here is some sample code using the techniques that are in your example.
I am passing an array from a client to a middle layer for further
processing. at the very in, I'll a message 'the server threw an
exception'. If you can help me resolve this I will appreciate it very
much.

Please note rfWhereFilter and ParamArray are an array[0..1] of string

{ server code}
procedure TGenRptEngine.AssignWhereFilter(vData: OleVariant);
var
aFilterString : Array of ParamArray ;
pData : PByteArray;

begin

setlength( aFilterString,1);

pData := VarArrayLock( vData ) ;
try

Move( pData^, AFilterString, SizeOf( aFilterString )) ;

finally
VarArrayUnLock( vData ) ;
end;
THE CODE APPEARS TO WORK FINE DOWN TO THIS POINT AS I TESTED IT WITH
MESSAGE BOXES.
ANY ATTEMPT TO ACCESS AN ARRAY ELEMENT WILL GENERATE AN EXCEPTION.
Form1.AssignSelectFilters( aFilterString );

end;
{ END OF SERVER CODE}
{ CLIENT CODE }
procedure TForm1.Button2Click(Sender: TObject);
Var
AWhereFilter : Array of rfWhereFilter ;
VData : Variant;
PData : PByteArray;
begin
cdsFilterString.First ;
{ the data is loaded from a client dataset into an array and then an ole
variant. The client dataset is being temporarily as the final data will
be be read from the registry into an array}

while not cdsFilterString.Eof do begin
{if High( aWhereFilter ) = -1 then
SetLength( aWhereFilter, 1 )
else }
SetLength( aWhereFilter, Max( High(aWhereFilter ) + 1,1) ) ;
aWhereFilter[ High(aWhereFilter),0] := cdsFilterStringCompName.asString ;
aWhereFilter[ High(aWhereFilter),1] := cdsFilterStringCompValue.asString ;
cdsFilterString.Next ;
end;
if High( aWhereFilter ) > -1 then
VData := VarArrayCreate( [0, SizeOf( aWhereFilter ) - 1], varByte );
PData := VarArrayLock( vData ) ;
try
Move(aWhereFilter, PData^, SizeOf(aWhereFilter) ) ;
Finally
VarArrayUnLock( vData ) ;
end;
GenRptEngine.AssignWhereFilter( vData );

{END OF CLIENT CODE}




Back to top
RandChris
Guest





PostPosted: Fri Apr 02, 2004 9:53 pm    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote

References: <406c99f9$1 (AT) newsgroups (DOT) borland.com> <406dbd5a (AT) newsgroups (DOT) borland.com>
In-Reply-To: <406dbd5a (AT) newsgroups (DOT) borland.com>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 12.109.22.4
Message-ID: <406de0ce$1 (AT) newsgroups (DOT) borland.com>
X-Trace: newsgroups.borland.com 1080942798 12.109.22.4 (2 Apr 2004 13:53:18 -0800)
Lines: 141
Path: number1.nntp.ash.giganews.com!internal1.nntp.ash.giganews.com!border2.nntp.ash.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
Xref: number1.nntp.ash.giganews.com borland.public.delphi.database.multi-tier:45763

Is there a way that you can show this using a 2 dimensional array of
strings being passed from the client to the server. Most importantly I
need to see a 2 dimension array of strings. I can figure how to reverse
the data flow.

Tony Blomfield wrote:
Quote:
Here is an working example straigh from a working project. Hope it helps.

Client Side:

procedure TDMCache.GetServerCacheCheckSumArray;
//Transfer the Array of Cache Checksums from the Appserver to the client as
a ByteStream
var
PData: PByteArray;
VData: Variant;
begin
FillChar(FServerMaxCacheIDs, SizeOf(FServerMaxCacheIDs), #0);
Appinfo.RemoteServer.Appserver.AS_GetCacheSumArray(VData);
PData := VarArrayLock(VData);
try
move(PData^, FServerMaxCacheIDs, SizeOf(FServerMaxCacheIDs));
finally
VarArrayUnlock(VData);
end;
end;


Server Side:


procedure TCIDG_RDM.AS_GetCacheSumArray(var CacheSumArray: OleVariant);
var
i : Integer;
TempArray : array[TCacheTableID] of Integer;
PData : PByteArray;
begin
// HelperObject.Logit(nil, 'AS_GetCacheSumArray', kProcedure);
DMCache.GetCacheSumArray(CacheSumArray);
PData:= VarArrayLock(CacheSumArray);
try
move(PData^, TempArray, Sizeof(TempArray));
for i:= 0 to length(FMaxOwnerLevelCacheIDs) - 1 do
begin
TempArray[TCacheTableID(i)]:= TempArray[TCacheTableID(i)] +
FMaxOwnerLevelCacheIDs[TCacheTableID(i)];
end;
move(TempArray, PData^, Sizeof(TempArray));
finally
VarArrayUnlock(CacheSumArray);
end;

end;









"RandChris" <RCoyle (AT) pfshouston (DOT) com> wrote in message
news:406c99f9$1 (AT) newsgroups (DOT) borland.com...

This technique is derived, as best as possible, from the article
http://community.borland.com/article/0,1410,25982,00.htm.
I get an arror from the server portion when attempting execute. The
point at which the error occurs is indicated in upper case notation.

Here is some sample code using the techniques that are in your example.
I am passing an array from a client to a middle layer for further
processing. at the very in, I'll a message 'the server threw an
exception'. If you can help me resolve this I will appreciate it very

much.

Please note rfWhereFilter and ParamArray are an array[0..1] of string

{ server code}
procedure TGenRptEngine.AssignWhereFilter(vData: OleVariant);
var
aFilterString : Array of ParamArray ;
pData : PByteArray;

begin

setlength( aFilterString,1);

pData := VarArrayLock( vData ) ;
try

Move( pData^, AFilterString, SizeOf( aFilterString )) ;

finally
VarArrayUnLock( vData ) ;
end;
THE CODE APPEARS TO WORK FINE DOWN TO THIS POINT AS I TESTED IT WITH
MESSAGE BOXES.
ANY ATTEMPT TO ACCESS AN ARRAY ELEMENT WILL GENERATE AN EXCEPTION.
Form1.AssignSelectFilters( aFilterString );

end;
{ END OF SERVER CODE}
{ CLIENT CODE }
procedure TForm1.Button2Click(Sender: TObject);
Var
AWhereFilter : Array of rfWhereFilter ;
VData : Variant;
PData : PByteArray;
begin
cdsFilterString.First ;
{ the data is loaded from a client dataset into an array and then an ole
variant. The client dataset is being temporarily as the final data will
be be read from the registry into an array}

while not cdsFilterString.Eof do begin
{if High( aWhereFilter ) = -1 then
SetLength( aWhereFilter, 1 )
else }
SetLength( aWhereFilter, Max( High(aWhereFilter ) + 1,1) ) ;
aWhereFilter[ High(aWhereFilter),0] := cdsFilterStringCompName.asString ;
aWhereFilter[ High(aWhereFilter),1] := cdsFilterStringCompValue.asString ;
cdsFilterString.Next ;
end;
if High( aWhereFilter ) > -1 then
VData := VarArrayCreate( [0, SizeOf( aWhereFilter ) - 1], varByte );
PData := VarArrayLock( vData ) ;
try
Move(aWhereFilter, PData^, SizeOf(aWhereFilter) ) ;
Finally
VarArrayUnLock( vData ) ;
end;
GenRptEngine.AssignWhereFilter( vData );

{END OF CLIENT CODE}






Back to top
RandChris
Guest





PostPosted: Fri Apr 02, 2004 10:32 pm    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote

References: <406c99f9$1 (AT) newsgroups (DOT) borland.com> <406dbd5a (AT) newsgroups (DOT) borland.com>
In-Reply-To: <406dbd5a (AT) newsgroups (DOT) borland.com>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 12.109.22.4
Message-ID: <406dea0b$1 (AT) newsgroups (DOT) borland.com>
X-Trace: newsgroups.borland.com 1080945163 12.109.22.4 (2 Apr 2004 14:32:43 -0800)
Lines: 138
Path: number1.nntp.ash.giganews.com!internal1.nntp.ash.giganews.com!border2.nntp.ash.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
Xref: number1.nntp.ash.giganews.com borland.public.delphi.database.multi-tier:45764

what is the value of FMaxOwnerLevelCacheIDs and how is it derived?

Tony Blomfield wrote:
Quote:
Here is an working example straigh from a working project. Hope it helps.

Client Side:

procedure TDMCache.GetServerCacheCheckSumArray;
//Transfer the Array of Cache Checksums from the Appserver to the client as
a ByteStream
var
PData: PByteArray;
VData: Variant;
begin
FillChar(FServerMaxCacheIDs, SizeOf(FServerMaxCacheIDs), #0);
Appinfo.RemoteServer.Appserver.AS_GetCacheSumArray(VData);
PData := VarArrayLock(VData);
try
move(PData^, FServerMaxCacheIDs, SizeOf(FServerMaxCacheIDs));
finally
VarArrayUnlock(VData);
end;
end;


Server Side:


procedure TCIDG_RDM.AS_GetCacheSumArray(var CacheSumArray: OleVariant);
var
i : Integer;
TempArray : array[TCacheTableID] of Integer;
PData : PByteArray;
begin
// HelperObject.Logit(nil, 'AS_GetCacheSumArray', kProcedure);
DMCache.GetCacheSumArray(CacheSumArray);
PData:= VarArrayLock(CacheSumArray);
try
move(PData^, TempArray, Sizeof(TempArray));
for i:= 0 to length(FMaxOwnerLevelCacheIDs) - 1 do
begin
TempArray[TCacheTableID(i)]:= TempArray[TCacheTableID(i)] +
FMaxOwnerLevelCacheIDs[TCacheTableID(i)];
end;
move(TempArray, PData^, Sizeof(TempArray));
finally
VarArrayUnlock(CacheSumArray);
end;

end;









"RandChris" <RCoyle (AT) pfshouston (DOT) com> wrote in message
news:406c99f9$1 (AT) newsgroups (DOT) borland.com...

This technique is derived, as best as possible, from the article
http://community.borland.com/article/0,1410,25982,00.htm.
I get an arror from the server portion when attempting execute. The
point at which the error occurs is indicated in upper case notation.

Here is some sample code using the techniques that are in your example.
I am passing an array from a client to a middle layer for further
processing. at the very in, I'll a message 'the server threw an
exception'. If you can help me resolve this I will appreciate it very

much.

Please note rfWhereFilter and ParamArray are an array[0..1] of string

{ server code}
procedure TGenRptEngine.AssignWhereFilter(vData: OleVariant);
var
aFilterString : Array of ParamArray ;
pData : PByteArray;

begin

setlength( aFilterString,1);

pData := VarArrayLock( vData ) ;
try

Move( pData^, AFilterString, SizeOf( aFilterString )) ;

finally
VarArrayUnLock( vData ) ;
end;
THE CODE APPEARS TO WORK FINE DOWN TO THIS POINT AS I TESTED IT WITH
MESSAGE BOXES.
ANY ATTEMPT TO ACCESS AN ARRAY ELEMENT WILL GENERATE AN EXCEPTION.
Form1.AssignSelectFilters( aFilterString );

end;
{ END OF SERVER CODE}
{ CLIENT CODE }
procedure TForm1.Button2Click(Sender: TObject);
Var
AWhereFilter : Array of rfWhereFilter ;
VData : Variant;
PData : PByteArray;
begin
cdsFilterString.First ;
{ the data is loaded from a client dataset into an array and then an ole
variant. The client dataset is being temporarily as the final data will
be be read from the registry into an array}

while not cdsFilterString.Eof do begin
{if High( aWhereFilter ) = -1 then
SetLength( aWhereFilter, 1 )
else }
SetLength( aWhereFilter, Max( High(aWhereFilter ) + 1,1) ) ;
aWhereFilter[ High(aWhereFilter),0] := cdsFilterStringCompName.asString ;
aWhereFilter[ High(aWhereFilter),1] := cdsFilterStringCompValue.asString ;
cdsFilterString.Next ;
end;
if High( aWhereFilter ) > -1 then
VData := VarArrayCreate( [0, SizeOf( aWhereFilter ) - 1], varByte );
PData := VarArrayLock( vData ) ;
try
Move(aWhereFilter, PData^, SizeOf(aWhereFilter) ) ;
Finally
VarArrayUnLock( vData ) ;
end;
GenRptEngine.AssignWhereFilter( vData );

{END OF CLIENT CODE}






Back to top
RandChris
Guest





PostPosted: Fri Apr 02, 2004 11:33 pm    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote

References: <406c99f9$1 (AT) newsgroups (DOT) borland.com> <406dbd5a (AT) newsgroups (DOT) borland.com>
In-Reply-To: <406dbd5a (AT) newsgroups (DOT) borland.com>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 12.109.22.4
Message-ID: <406df82f$1 (AT) newsgroups (DOT) borland.com>
X-Trace: newsgroups.borland.com 1080948783 12.109.22.4 (2 Apr 2004 15:33:03 -0800)
Lines: 141
Path: number1.nntp.ash.giganews.com!internal1.nntp.ash.giganews.com!border2.nntp.ash.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
Xref: number1.nntp.ash.giganews.com borland.public.delphi.database.multi-tier:45765

This is interesting. I can make this work, but not with dynamic arrays.
Also, I use the function findcomponent in the middle tier with a
component name that is passed as a string and it will generate a
catastrophic error.

Tony Blomfield wrote:
Quote:
Here is an working example straigh from a working project. Hope it helps.

Client Side:

procedure TDMCache.GetServerCacheCheckSumArray;
//Transfer the Array of Cache Checksums from the Appserver to the client as
a ByteStream
var
PData: PByteArray;
VData: Variant;
begin
FillChar(FServerMaxCacheIDs, SizeOf(FServerMaxCacheIDs), #0);
Appinfo.RemoteServer.Appserver.AS_GetCacheSumArray(VData);
PData := VarArrayLock(VData);
try
move(PData^, FServerMaxCacheIDs, SizeOf(FServerMaxCacheIDs));
finally
VarArrayUnlock(VData);
end;
end;


Server Side:


procedure TCIDG_RDM.AS_GetCacheSumArray(var CacheSumArray: OleVariant);
var
i : Integer;
TempArray : array[TCacheTableID] of Integer;
PData : PByteArray;
begin
// HelperObject.Logit(nil, 'AS_GetCacheSumArray', kProcedure);
DMCache.GetCacheSumArray(CacheSumArray);
PData:= VarArrayLock(CacheSumArray);
try
move(PData^, TempArray, Sizeof(TempArray));
for i:= 0 to length(FMaxOwnerLevelCacheIDs) - 1 do
begin
TempArray[TCacheTableID(i)]:= TempArray[TCacheTableID(i)] +
FMaxOwnerLevelCacheIDs[TCacheTableID(i)];
end;
move(TempArray, PData^, Sizeof(TempArray));
finally
VarArrayUnlock(CacheSumArray);
end;

end;









"RandChris" <RCoyle (AT) pfshouston (DOT) com> wrote in message
news:406c99f9$1 (AT) newsgroups (DOT) borland.com...

This technique is derived, as best as possible, from the article
http://community.borland.com/article/0,1410,25982,00.htm.
I get an arror from the server portion when attempting execute. The
point at which the error occurs is indicated in upper case notation.

Here is some sample code using the techniques that are in your example.
I am passing an array from a client to a middle layer for further
processing. at the very in, I'll a message 'the server threw an
exception'. If you can help me resolve this I will appreciate it very

much.

Please note rfWhereFilter and ParamArray are an array[0..1] of string

{ server code}
procedure TGenRptEngine.AssignWhereFilter(vData: OleVariant);
var
aFilterString : Array of ParamArray ;
pData : PByteArray;

begin

setlength( aFilterString,1);

pData := VarArrayLock( vData ) ;
try

Move( pData^, AFilterString, SizeOf( aFilterString )) ;

finally
VarArrayUnLock( vData ) ;
end;
THE CODE APPEARS TO WORK FINE DOWN TO THIS POINT AS I TESTED IT WITH
MESSAGE BOXES.
ANY ATTEMPT TO ACCESS AN ARRAY ELEMENT WILL GENERATE AN EXCEPTION.
Form1.AssignSelectFilters( aFilterString );

end;
{ END OF SERVER CODE}
{ CLIENT CODE }
procedure TForm1.Button2Click(Sender: TObject);
Var
AWhereFilter : Array of rfWhereFilter ;
VData : Variant;
PData : PByteArray;
begin
cdsFilterString.First ;
{ the data is loaded from a client dataset into an array and then an ole
variant. The client dataset is being temporarily as the final data will
be be read from the registry into an array}

while not cdsFilterString.Eof do begin
{if High( aWhereFilter ) = -1 then
SetLength( aWhereFilter, 1 )
else }
SetLength( aWhereFilter, Max( High(aWhereFilter ) + 1,1) ) ;
aWhereFilter[ High(aWhereFilter),0] := cdsFilterStringCompName.asString ;
aWhereFilter[ High(aWhereFilter),1] := cdsFilterStringCompValue.asString ;
cdsFilterString.Next ;
end;
if High( aWhereFilter ) > -1 then
VData := VarArrayCreate( [0, SizeOf( aWhereFilter ) - 1], varByte );
PData := VarArrayLock( vData ) ;
try
Move(aWhereFilter, PData^, SizeOf(aWhereFilter) ) ;
Finally
VarArrayUnLock( vData ) ;
end;
GenRptEngine.AssignWhereFilter( vData );

{END OF CLIENT CODE}






Back to top
Bill Todd (TeamB)
Guest





PostPosted: Sat Apr 03, 2004 12:22 am    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote

On Fri, 02 Apr 2004 15:53:21 -0600, RandChris <RCoyle (AT) pfshouston (DOT) com>
wrote:

Quote:
Is there a way that you can show this using a 2 dimensional array of
strings being passed from the client to the server. Most importantly I
need to see a 2 dimension array of strings. I can figure how to reverse
the data flow.

Take a look in the Language Reference at the explanation of how Delphi
strings are stored and you will see why this will not work. It works
with static arrays of fixed size values because the data are stored in
adjacent bytes in memory. Strings are not stored that way. Delphi
strings are basically pointers to dynamically allocated blocks of
memory. There is no continuous stream of bytes that can be copied to a
byte array.

--
Bill (TeamB)
(TeamB cannot respond to questions received via email)

Back to top
Rafel Coyle
Guest





PostPosted: Sat Apr 03, 2004 1:43 am    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote

References: <406c99f9$1 (AT) newsgroups (DOT) borland.com> <406dbd5a (AT) newsgroups (DOT) borland.com> <406de0ce$1 (AT) newsgroups (DOT) borland.com> <u80s605nqj0i8j1nnan79k7hb0laioiel9 (AT) 4ax (DOT) com>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 24.233.62.5
X-Trace: newsgroups.borland.com 1080956626 24.233.62.5 (2 Apr 2004 17:43:46 -0800)
Lines: 31
Path: number1.nntp.ash.giganews.com!internal1.nntp.ash.giganews.com!border2.nntp.ash.giganews.com!nntp.giganews.com!feed2.newsreader.com!newsreader.com!newshosting.com!nx02.iad01.newshosting.com!203.109.252.33.MISMATCH!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail
Xref: number1.nntp.ash.giganews.com borland.public.delphi.database.multi-tier:45767

Thank you.

Now I will have to find a way to make findcomponent work in the middle
tier app. There I have a form with a tabsheet that is the parent of a
frame. Findcomponent works if I run the server app as a program, but if
I call it as an automation server an error is generated in the middle
tier app.

Bill Todd (TeamB) wrote:
Quote:
On Fri, 02 Apr 2004 15:53:21 -0600, RandChris wrote:


Is there a way that you can show this using a 2 dimensional array of
strings being passed from the client to the server. Most importantly I
need to see a 2 dimension array of strings. I can figure how to reverse
the data flow.


Take a look in the Language Reference at the explanation of how Delphi
strings are stored and you will see why this will not work. It works
with static arrays of fixed size values because the data are stored in
adjacent bytes in memory. Strings are not stored that way. Delphi
strings are basically pointers to dynamically allocated blocks of
memory. There is no continuous stream of bytes that can be copied to a
byte array.

--
Bill (TeamB)
(TeamB cannot respond to questions received via email)


Back to top
Bill Todd (TeamB)
Guest





PostPosted: Sat Apr 03, 2004 2:45 am    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote

By the way, as someone else pointed out in this thread, it should work
if you use the old style Pascal short strings. For example,

Foo: array[0..9] of String[40];

--
Bill (TeamB)
(TeamB cannot respond to questions received via email)
Back to top
Rafel Coyle
Guest





PostPosted: Sat Apr 03, 2004 6:44 am    Post subject: Re: Passing a two dimensional array from client app to middl Reply with quote

References: <406c99f9$1 (AT) newsgroups (DOT) borland.com> <406dbd5a (AT) newsgroups (DOT) borland.com> <406de0ce$1 (AT) newsgroups (DOT) borland.com> <u80s605nqj0i8j1nnan79k7hb0laioiel9 (AT) 4ax (DOT) com> <406E16D5.1080709 (AT) nospamplspfshouston (DOT) com> <e79s601ppv7n3vt4eqn3mdei4ppv18l47i (AT) 4ax (DOT) com>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 24.233.62.5
X-Trace: newsgroups.borland.com 1080974681 24.233.62.5 (2 Apr 2004 22:44:41 -0800)
Lines: 12
Path: number1.nntp.ash.giganews.com!internal1.nntp.ash.giganews.com!border2.nntp.ash.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
Xref: number1.nntp.ash.giganews.com borland.public.delphi.database.multi-tier:45770

Thanks Bill. Actually, I used Array[0..20] of array[0..1] of string[30]

Bill Todd (TeamB) wrote:
Quote:
By the way, as someone else pointed out in this thread, it should work
if you use the old style Pascal short strings. For example,

Foo: array[0..9] of String[40];

--
Bill (TeamB)
(TeamB cannot respond to questions received via email)


Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Databases (Multi-Tier) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.