在三层中怎样传一个动态数组类型?用静态的很好就搞定了,但用动态的却不行。 (100分)

  • 主题发起人 主题发起人 databox
  • 开始时间 开始时间
D

databox

Unregistered / Unconfirmed
GUEST, unregistred user!
我用类似于下面这种方法,传送一个类型可以,但我要传一个动态数组类型,又怎么做呢?
我想,主要是Move那儿,我不太清楚如何做。请大伙儿帮帮忙。
类型例子。
type
rAccReg = Record
sValue: String;
cType: Integer;
end;
type
rAccountReg = Record
AccReg: array[0..1023] of rAccReg;
AccNum: Integer;
end;
我要传一个array of 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;
 
做个转换,先把你的内容读入MemoryStream,再转成OleVariant
另一端反过来!
procedure VariantToStream(const Data: OleVariant;
Stream: TStream);
var
p: Pointer;
begin
p := VarArrayLock(Data);
try
Stream.Write(p^, VarArrayHighBound(Data,1) + 1);
//assuming low bound = 0
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;
//start from begin
ning of stream
Stream.Read(p^, Stream.Size);
finally
VarArrayUnlock(Result);
end;
end;
 
GanQuan, 不用MemoryStream行不?有没有别的方法?
 
当然可以!
使用stream只是为了统一接口传输方法。
你可以一项一项的把你的内容写道Variant中去。就像上面代码中Stream写到Variant中一样。
我看你也是这样做的。
不过,我看你的代码中有个问题。
>>Move(AccountReg,P^,Sizeof(rAccountReg));
你直接用结构的sizeof来写结构内容,这样会导致问题。
一个结构的sizeof并不一定等于它里面各项内容的长度之和。
比如
rAccReg = Record
sValue: String;
cType: Integer;
end;
record的sizeof只是一个字符串指针和一个整型的sizeof的和8。
如果你的svalue有值 svalue:= 'sdflsakdjfklsdjflsdkjfdslf';
那么你的svalue的length就比record的sizeof大,这样你用record的
sizeof写入读出当然会出错!
你可以一项一项的写入读出,当然顺序要自己控制。
 
GanQuan,用MemoryStream不失为一个好方法,但我也想知道怎样自己来控制。你能帮我示范
一下吗?我就是不太清楚怎么一项一项的读出或写入。
 
我发觉如果我设定为静态数组,然后传入Variant中,再传出来就可以。
但如果我是设定的动态数组,哪怕前后一模一样,但以上VarArrayCreate的方法却不可行啦。
谁能帮我说说为什么和怎样解决?
 
procedure TCommClient.DoOnData(aData: OleVariant;
const aSource: WideString;
out aAction: Integer);
var
S : TMemoryStream;
P : Pointer;
L : Integer;
begin
if Assigned(FOnData) then
try
S := TMemoryStream.Create;
try
//将传过来的安全数组转换为TStream类型,触发事件
L := VarArrayHighBound(aData, 1) - VarArrayLowBound(aData, 1) + 1;
P := VarArrayLock(aData);
try
S.Seek(0, soFrombegin
ning);
S.WriteBuffer(P^, L);
finally
VarArrayUnlock(aData);
end;

FOnData (Self, S, aSource, aAction);
finally
S.Free
end;
except
on E: Exception do
begin
TLogFile.WriteLn('数据接收处理出错, 错误信息="%s"', [E.Message]);
end;
end;
end;
 
后退
顶部