简体   繁体   English

在dwscript中使用/注入在Delphi中实现的接口实例

[英]Using / injecting an interface instance implemented in Delphi in dwscript

I have an interface (in fact multiple interfaces) which I'd like to use this way: 我有一个接口(实际上是多个接口),我想使用这种方式:

  • Make Units where the interfaces are declared available inside the dwscript script (if neccessary). 使声明了接口的单元在dwscript脚本内(如有必要)可用。

  • Create the objects, that implement the interfaces, in the host application written in Delphi. 在用Delphi编写的主机应用程序中创建实现接口的对象。

  • Make those interfaces available in some way to the dwscript script. 使这些接口以某种方式可用于dwscript脚本。

  • And use them normally inside the script. 并在脚本中正常使用它们。

Is there any possibility to do so? 有可能这样做吗?

I tried to provide methods returning those interfaces in a class, but when I used this class over RTTI those methods where not found. 我试图提供在类中返回这些接口的方法,但是当我在RTTI上使用此类时,找不到那些方法。

As I stated above it isn't immediately possible to declare an interface and implement it Delphi side with a TdwsUnit . 正如我在上面所述,不可能立即声明接口并使用TdwsUnit在Delphi端实现它。 It is however possible to achieve what you're after in other ways. 但是,可以通过其他方式实现您的追求。

I'm assuming that you have declared both your interface and your class in a TdwsUnit . 我假设您已经在TdwsUnit声明了接口和类。 Let's call them IMyInterface and TMyClass . 让我们把他们IMyInterfaceTMyClass

type
  IMyInterface = interface
    procedure SetValue(const Value: string);
    function GetValue: string;
    property Value: string read GetValue write SetValue;
    procedure DoSomething;
  end;

type
  TMyClass = class(TObject)
  protected
    procedure SetValue(const Value: string);
    function GetValue: string;
  public
    property Value: string read GetValue write SetValue;
    procedure DoSomething;
  end;

Solution 1 - Alter the class declaration at run time 解决方案1-在运行时更改类声明

Create an event handler for the TdwsUnit.OnAfterInitUnitTable event and add the interface to the class declaration: TdwsUnit.OnAfterInitUnitTable事件创建一个事件处理程序,并将接口添加到类声明中:

procedure TDataModuleMyStuff.dwsUnitMyStuffAfterInitUnitTable(Sender: TObject);
var
  ClassSymbol: TClassSymbol;
  InterfaceSymbol: TInterfaceSymbol;
  MissingMethod: TMethodSymbol;
begin
  // Add IMyInterface to TMyClass
  ClassSymbol := (dwsUnitProgress.Table.FindTypeLocal('TMyClass') as TClassSymbol);
  InterfaceSymbol := (dwsUnitProgress.Table.FindTypeLocal('IMyInterface') as TInterfaceSymbol);
  ClassSymbol.AddInterface(InterfaceSymbol, cvProtected, MissingMethod);
end;

Now you can access an instance of the class though an interface in your script: 现在,您可以通过脚本中的接口访问该类的实例:

var MyStuff: IMyInterface;
MyStuff := TMyObject.Create;
MyStuff.DoSomething;

Solution 2 - Use duck typing 解决方案2-使用鸭子打字

Since DWScript supports duck typing you don't actually need to declare that your class implements an interface. 由于DWScript支持鸭子类型,因此您实际上不需要声明您的类实现了接口。 Instead you just state what interface you need and let the compiler figure out if the object can satisfy that need: 相反,您只需要声明所需的接口,然后让编译器确定对象是否可以满足该需求:

var MyStuff: IMyInterface;
MyStuff := TMyObject.Create as IMyInterface;
MyStuff.DoSomething;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM