在Delphi中利用VisiBroker开发三层的Corba应用如何返回一个自定义的类或者是Delphi的内部类(如TStringGrid类)。
急呀,大虾们请帮帮忙呀。

解决方案 »

  1.   

    恩,对,你把你要返回的东西都放到一个 OleVariant 里面,如果是类的话要注意里面变量的地址。你需要写个东西,把类打包到 OleVariant,然后还要有一个解包的东东就行了。
      

  2.   

    大虾,具体怎么做能不能做个Sample给我。
      

  3.   

    就是怎么把一个东西打包到OleVariant里
      

  4.   

    我先跟你说一下思路吧。你得好好研究一下内存、指针什么,上次我写这个玩艺是很早以前了,都忘的差不多了。
    就是先把类放到连续的内存中
    这是一个类:
    Class
     |---int
     |---int
     |---String
    有三个成员,他们在内存中时,int 和类是在一起的,但是String是存在另一个地方,只是把指针和类放在一起了。所以要解决的就是把 String 弄过来然后,你就可以把这一连续的内存放到 OleVariant 中了。
    传~~,到地方之后解来包就行了。一个简单测试上面是不是正确的方法:
    写个函数,把那连续内存存到一文件中。重启,再读出那文件,看看能不能把类还原就行了。像上面那个类,写到连续内存中应该是这样子:
    =======================================
    类占内存大小 类实例 字符串大小 字符串值
    =======================================
    中间没有空格CopyMemory 可以用来内存的复制1.算出类实际要的内存大小,按上面连续内存的格式,int 大小 + 类本身大小 + int + 字符串大小
    2.申请这么大的内存
    3.复制内存,先把类本身大小copy到内存的0位置上,再把类复制到后面,再存字符串大小,再去字符串复制到后在
    就OK了
      

  5.   

    我以前写的一个小类的:  TAbstractField = class
      Private
        fOnValueChanged : TNotifyEvent;
      public
        OldValue : Variant;
        function Size : Integer;
        function Fix(OutMemory : Pointer) : Integer;
        procedure UnFix(OutMemory : Pointer);
        constructor Create;
        destructor Destroy; override;
      private
        fValue : Variant;
        procedure SetValue(prmValue : Variant);
      published
        property Value : Variant read fValue write SetValue ;
        Property OnValueChanged:TNotifyEvent Read fOnValueChanged Write fOnValueChanged;
      end;=-----
    其中内容://---------------------------------------------------------TAbstractField.Size//
    function TAbstractField.Size : Integer;
    //计算类的大小
    var
      sTemp : AnsiString;
    begin
      Result := Self.InstanceSize;
      //计算fValue的大小
      case VarType(fValue) of
        VarString, VarOleStr :
        begin
          sTemp := fValue;
          Result := Result + length(sTemp) + 1;
        end;
      end;  //计算OldValue的大小
      case VarType(OldValue) of
        VarString, VarOleStr :
        begin
          sTemp := OldValue;
          Result := Result + length(sTemp) + 1;
        end;
      end;
    end;//----------------------------------------------------------TAbstractField.Fix//
    function TAbstractField.Fix(OutMemory : Pointer) : Integer;
    //把类放入连续内存
    var
      iPointer : Pointer;
      iSize : Integer;
      sTemp : AnsiString;
      pchSou : pChar;
    begin
      iPointer := OutMemory;  //放入类本身
      iSize := Self.InstanceSize;
      CopyMemory(iPointer, Self, iSize);
      Integer(iPointer) := Integer(iPointer) + iSize;
      Result := iSize;  //放入fValue值
      case VarType(fValue) of
        VarString, VarOleStr :
        begin
          sTemp := fValue;
          iSize := length(sTemp) + 1;
          GetMem(pchSou, iSize);
          StrCopy(pchSou, pChar(sTemp));
          StrCopy(iPointer, pchSou);
          Integer(iPointer) := Integer(iPointer) + iSize;
          Result := Result + iSize;
        end;
      end; //case  //放入OldValue值
      case VarType(OldValue) of
        VarString, VarOleStr :
        begin
          sTemp := OldValue;
          iSize := length(sTemp) + 1;
          GetMem(pchSou, iSize);
          StrCopy(pchSou, pChar(sTemp));
          StrCopy(iPointer, pchSou);
          Integer(iPointer) := Integer(iPointer) + iSize;
          Result := Result + iSize;
        end;
      end; //case
    end;//--------------------------------------------------------TAbstractField.UnFix//
    procedure TAbstractField.UnFix(OutMemory : Pointer);
    //把类从连续内存中取出来
    var
      pchPtr : pChar;
    begin
      pchPtr := pChar(OutMemory) + Self.InstanceSize;  case VarType(TAbstractField(OutMemory).Value) of
        VarString, VarOleStr :
        begin
          Self.fValue := WideString(pchPtr);
          pchPtr := pchPtr + strlen(pchPtr) + 1;
        end;
      else
        Self.fValue := TAbstractField(OutMemory).fValue;
      end; //case  case VarType(TAbstractField(OutMemory).OldValue) of
        VarString, VarOleStr :
        begin
          Self.OldValue := WideString(pchPtr);
          pchPtr := pchPtr + strlen(pchPtr) + 1;
        end;
      else
        Self.OldValue := TAbstractField(OutMemory).OldValue;
      end; //case
    end;
      

  6.   

    调用方法:
    打包:
    procedure TfrmClientMain.btnfixClick(Sender: TObject);
    var
      iSize : Integer;
      iPointer : Pointer;
      p : pointer;
      varData : OleVariant;
    begin
      iSize := AbstractField.Size;
      iPointer := AllocMem(iSize);
      ShowMessage('申请了 ' + IntToStr(iSize) + ' 个字节,使用了 ' + IntToStr(AbstractField.Fix(iPointer)) + ' 个');
      varData := VarArrayCreate([0, iSize - 1], varByte);
      p := VarArrayLock(varData);
      CopyMemory(p, iPointer, iSize);
      VarArrayUnlock(varData);
      Send(varData);
      Freemem(iPointer);
    end;解包:
    procedure TfrmClientMain.Send(varData : OleVariant);
    var
      iSize : Integer;
      p, p2 : Pointer;
      iIndex : Integer;
    begin
      ComboBox2.Clear;
      AbstractField:= TAbstractField.Create();
      iSize := VarArrayHighBound(varData, 1) + 1;
      p2 := AllocMem(iSize);
      p := VarArrayLock(varData);
      CopyMemory(p2, p, iSize);
      VarArrayUnlock(varData);
      AbstractField.UnFix(p);
    end;