在DELPHI的三层结构中,客户端和服务器端的数据传输都是通过OleVariant类型来处理的!
虽然OleVariant是强类型,但操作的时候确非常困难!
比如,我定了一个类
type
taaa = class
a1 ,a2 : integer;
a3 : OleVariant;
end;var x : taaa;
begin
x := taaa.create;
x.a1 := 100;
x.a2 := 1;
x.a3 := 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
clientdataset1.datarequest(x);//要产生异常!
end;在这种情况下,在客户端怎么把刚才定义的类打包为OleVariant类型,并传递到服务器端
服务器端在接收到该类型数据后,仍然是OleVariant类型,我又怎么将其还原为Taaa类型?
虽然OleVariant是强类型,但操作的时候确非常困难!
比如,我定了一个类
type
taaa = class
a1 ,a2 : integer;
a3 : OleVariant;
end;var x : taaa;
begin
x := taaa.create;
x.a1 := 100;
x.a2 := 1;
x.a3 := 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
clientdataset1.datarequest(x);//要产生异常!
end;在这种情况下,在客户端怎么把刚才定义的类打包为OleVariant类型,并传递到服务器端
服务器端在接收到该类型数据后,仍然是OleVariant类型,我又怎么将其还原为Taaa类型?
var
cnn:OLevariant;
procedure TForm1.FormCreate(Sender: TObject);
begin
cnn:=createoleobject('ADODB.Connection');
Adoconnection1.ConnectionString:=cnn.ConnectionString;
end;
或者两个都是返回OLevariant类型,直接赋值如
ClientDataSet1.Data := DataSetProvider1.Data;
ms: TStream; p: Pointer;
begin
ov := dmMain.ComConnection.AppServer.TimeZone;
ms := TMemoryStream.Create;
ms.Position := 0;
p := VarArrayLock(ov);
ms.Write(p^, VarArrayHighBound(ov, 1)); //這句可否改進?
VarArrayUnlock(ov); ms.Position := 0;
...
ms.Free;
end;Stream --> Variantfunction TTCanteenSvr.Get_TimeZone: OleVariant;
var
AStream: TStream;
MyBuffer: Pointer;
begin
try
AStream := TFileStream.Create(, fmOpenRead);
Result := VarArrayCreate([0, AStream.Size - 1], VarByte);
MyBuffer := VarArrayLock(Result);
AStream.ReadBuffer(MyBuffer^, AStream.Size);
VarArrayUnlock(Result);
finally
AStream.Free;
end;參考上面的例子, 應該就可實現你要的了
procedure TForm1.Button1Click(Sender: TObject);
var
a:olevariant;
b:_recordset;
begin
b := IUnKnown(a) as _recordset;
end;
unit UnitCommon;interfaceuses SysUtils, Classes,Service_TLB;Type
TDataTrans = class(Tobject , IUnKnown)
FDataSetId : Integer;
FDataOperId : Integer;
FDataDS : OleVariant;
private
procedure SetDataDs(const Value: OleVariant);
procedure SetDataOperId(const Value: Integer);
procedure SetDataSetID(const Value: Integer);
public
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
published
property DataSetID : Integer read FDataSetID write SetDataSetID;
Property DataOperId : Integer read FDataOperId write SetDataOperId;
Property DataDs : OleVariant read FDataDs write SetDataDs;
End;
implementationfunction TDataTrans.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
//
end;procedure TDataTrans.SetDataDs(const Value: OleVariant);
begin
FDataDs := Value;
end;procedure TDataTrans.SetDataOperId(const Value: Integer);
begin
FDataOperId := Value;
end;procedure TDataTrans.SetDataSetID(const Value: Integer);
begin
FDataSetID := Value;
end;function TDataTrans._AddRef: Integer;
begin
//
end;function TDataTrans._Release: Integer;
begin
//
end;end.
==========================================================================================function TDMBaseBo.ProviderSelectDataRequest(Sender: TObject;
Input: OleVariant): OleVariant;
var S : TDataTrans;
begin
inherited;
s := IUnknown(Input) as TDataTrans;
end;编译的时候还是会出现:
[Error] UDMBaseBO.pas(375): Operator not applicable to this operand type
错误!