2

私はこのDelphiクラスを持っています

type
  TAnotherClass = class
  end;

  TMyClass = class
    function Foo: TAnotherClass;
  end;

function TMyClass.Foo: TAnotherClass;
begin
  Result := TAnotherClass.Create;
end;

ここで、「dwsRTTIExposer.pas」を介してこのクラスを公開したいと思います。

myUnit.ExposeRTTI(TypeInfo(TMyClass));
myUnit.ExposeRTTI(TypeInfo(TAnotherClass));

私のスクリプトは次のようになります。

var a: TMyClass = TMyClass.Create;
var b: TAnotherClass;
b := a.Foo;

残念ながら、Delphi Web Script は、TMyClass.Foo からの戻り値を有効なスクリプト クラスとして認識しません。OnEval-Eventhandler を使用して各メソッドを手動で公開するためにフォールバックせずにそれを行う可能性はありますか?

4

1 に答える 1

2

ExposeRTTI は現在、クラス タイプのパラメーターをサポートしていません。

これは、Delphi オブジェクトのライフサイクルが任意で不定であるため、スクリプトで直接 Delphi クラスを返すと問題が発生する可能性があるためです (Delphi 側のオブジェクトはいつでも予告なしに破棄される可能性があります)。

各メソッドを手動で公開する必要はありません。基本型を含むすべてのメソッドに RTTI エクスポーザーを使用でき、クラス型を含むメソッドのみを手動で処理する必要があります。

その場合、スクリプト側のオブジェクトをどのように公開するか、Delphi 側のオブジェクトとの関係を決定する必要がありますが、これは RTTI では手掛かりがありません。

たとえば、元のコードでは、OnEval コードは、呼び出しごとにメソッド Result をラップする新しいスクリプト オブジェクトを作成するだけです。

しかし、その実装が次のように変更された場合でも、Foo の RTTI 署名はまったく同じです。

TMyClass = class
   private
      FFoo: TAnotherClass;
   public
      function Foo: TAnotherClass;
end;

function TMyClass.Foo: TAnotherClass;
begin
   if FFoo=nil then
      FFoo := TAnotherClass.Create;
   Result := FFoo;
end;

ただし、その場合、後続の呼び出しで同じスクリプト側オブジェクトを返す必要があるため、OnEval は完全に異なる必要があり、スクリプト側オブジェクトのデストラクタをフックして結果を適切に処理する必要もあります。プライベート FFoo フィールド。

Delphi が真にガベージ コレクション オブジェクトを持つようになると、制約が緩和される可能性がありますが、現在のところ、安全ではない TInterfacedObject だけに近づくことができます。また、手動のイベント ハンドラを使用して、循環参照や無効にするクラスなどを処理する必要があります。参照カウント (VCL コンポーネントと同様)。

于 2011-04-21T06:54:06.480 に答える