我想在客户端传递一个自定义类型的参数给服务器应用程序的方法,应怎样传递?(100分)

  • 主题发起人 主题发起人 xuexiaoyan
  • 开始时间 开始时间
X

xuexiaoyan

Unregistered / Unconfirmed
GUEST, unregistred user!
我想在客户端传递一个自定义类型的参数给服务器应用程序的方法,应怎样传递?
服务器端方法定义如下:
procedure TCliManagerApp.mTransaction(const userName: WideString;
AccountReg: OleVariant);
begin
...
end;

客户端:
type
rAccReg = Record
sValue: String;
cType: Integer;
end;
type
rAccountReg = Record
AccReg: array[0..1023] of rAccReg;
AccNum: Integer;
end;
AccountReg: rAccountReg;
调用
MailDataModule.SocketCon.AppServer.mTransaction(
UserName,
AccountReg
);
出错为类型不匹配,请问怎样解决?请各位赐教!!!
 
问题很急,那位大侠帮帮忙!
 
OleVariant只是系统预定义的数据类型对用户自己定义的数据类型传递是会出现错误,可以把
自己定义的类型分开为两个参数传递.
 
在服务器端的接口函数中不要用OLEVARIANT ,
而是也在 “服务端包含一份自定义的数据类型的声明”
procedure TCliManagerApp.mTransaction(const userName: WideString;
AccountReg: rAccountReg);
 
To 鱼干片子:
可是我在类型库里找不到自定义变量,难道要在代码里直接改?你能详细点吗?
 
你的理解有问题,服务器端用OleVariant没错,但并不是说OleVariant可以代表任何
数据结构,包括你自定义的rAccountReg在内。
实际上OleVariant只“代表”某些数据类型,其中一些还是不与COM兼容的,你可以
在VarType函数的Help中看看。
就你遇到的情形来看,可以采取两种方式解决:
(1)嵌套的Variant数组
AccountReg := VarArrayCreate([0,1], VarVariant);
AccountReg[1] := 123456;
// 假设 AccNum=123456
TempVar1 := VarArrayCreate([0,1023], VarVariant);
for i:=0 to 1023do
begin
TempVar2 := VarArrayCreate([0,1], VarVariant);
TemptVar2[0] := ??????;
// sValue的值
TemptVar2[1] := ??????;
// cType的值
TempVar1 := TempVar2;
end;
AccountReg[0] := TempVar1;
(2)ClientDataSet的Data
AccountReg := VarArrayCreate([0,1], VarVariant);
AccountReg[1] := 123456;
// 假设 AccNum=123456
TempData := TClientDataSet.Create(nil);
with TempDatado
try
with AddFieldDefdo
begin
Name := 'sValue';
DataType := ftString;
size := 40;
// 视需要而定
end;
with AddFieldDefdo
begin
Name := 'cType';
DataType := ftInteger;
end;
CreateDataSet;
for i:=0 to 1023do
begin
Append;
FieldByName('sValue').AsString := ??????;
// sValue的值
FieldByName('cType').AsInteger := ??????;
// cType的值
Post;
end;
AccountReg[0] := Data;
finally
Free;
end;


 
Variant数组很合适。
Data和Delta的数据格式未知,虽然很紧凑,但通用性不好!
(一家之言,不听也罢)。
 
可以用variant数组,最简单的用法如下:
客户端与服务端都定义rAccReg,rAccountReg结构。
客户端将结构变为Variant:
V:Variant;
P:pointer;
V:=VarArrayCreate([0,Sizeof(rAccountReg)],varByte);
P:=VarArrayLock(V);
Move(AccountReg,P^,Sizeof(rAccountReg));
VarArrayUnLock(V);
调用 mTransaction(UserName,AccountReg);
服务器端变回来:
procedure TCliManagerApp.mTransaction(const userName: WideString;
vAccountReg: OleVariant);
var AccountReg:rAccountReg;
begin
P:=VarArrayLock(vAccountReg);
Move(P^,AccountReg,Sizeof(rAccountReg));
VarArrayUnLock(vAccountReg);
end;

够清楚了吧?
给分,结束了吧!

 
同意guqs。
最近也在烦这个问题,在网上找到一段代码是Stream和OleVariant的转换。
这样可以不管是什么数据结构(包括文件),都可以转换成流,再转换成OleVariant
进行传递。不过在两端也需要知道数据结构组成,以便转换成Stream和从Stream中读出。
procedure VariantToStream(const Data: OleVariant;
Stream: TStream);
var
p: Pointer;
begin

p := VarArrayLock(Data);
try
Stream.Write(p^, VarArrayHighBound(Data,1) + 1);

finally
VarArrayUnlock(Data);
end;

end;

function StreamToVariant(Stream: TStream): OleVariant;
var
p: Pointer;
begin

Result := VarArrayCreate([0, Stream.Size - 1], varByte);
p := VarArrayLock(Result);
try
Stream.Position := 0;

Stream.Read(p^, Stream.Size);
finally
VarArrayUnlock(Result);
end;

end;

 
对了,你的结构里不能用 string,而要改为shortstring或widestring才行。
 
接受答案了.
 
to:guqs
你的代码怎么会在Delphi6做的中间层里有错?
 
后退
顶部