在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类型?

解决方案 »

  1.   

    OLevariant是类似这样用:
    var
      cnn:OLevariant;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      cnn:=createoleobject('ADODB.Connection');
      Adoconnection1.ConnectionString:=cnn.ConnectionString;
    end;
    或者两个都是返回OLevariant类型,直接赋值如
    ClientDataSet1.Data := DataSetProvider1.Data;
      

  2.   

    http://blog.csdn.net/aiirii/archive/2004/11/29/197386.aspx在Com, Dcom, Com+中經常要用到variant, 而在delphi 中的文件操作之類中, 更多的用到Stream, 有時, 需要適當的互換!Variant --> Streamvar ov: OleVariant;
      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;參考上面的例子, 應該就可實現你要的了
      

  3.   

    olevariant转换
    procedure TForm1.Button1Click(Sender: TObject);
    var
      a:olevariant;
      b:_recordset;
    begin
      b := IUnKnown(a) as _recordset;
    end;
      

  4.   

    不行!我都试过了!有没有其它方法呀!原码如下:
    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
    错误!