在 dwscript 中使用/注入在 Delphi 中实现的接口实例
Using / injecting an interface instance implemented in Delphi in dwscript
我有一个接口(实际上是多个接口),我想这样使用:
使声明接口的单元在 dwscript 脚本中可用(如果需要)。
在用 Delphi 编写的主机应用程序中创建实现接口的对象。
以某种方式使这些接口对 dwscript 脚本可用。
并在脚本中正常使用它们。
有没有可能这样做?
我试图提供在 class 中返回这些接口的方法,但是当我在 RTTI 上使用这个 class 时,找不到那些方法。
正如我上面所说的,不能立即声明一个接口并用 TdwsUnit
实现它 Delphi 端。但是,您可以通过其他方式实现您的目标。
我假设您已经在 TdwsUnit
中声明了您的接口和 class。我们称它们为 IMyInterface
和 TMyClass
.
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;
解决方案 1 - 在 运行 时间
更改 class 声明
为 TdwsUnit.OnAfterInitUnitTable
事件创建事件处理程序并将接口添加到 class 声明:
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;
现在您可以通过脚本中的接口访问 class 的实例:
var MyStuff: IMyInterface;
MyStuff := TMyObject.Create;
MyStuff.DoSomething;
解决方案 2 - 使用 duck typing
由于 DWScript 支持 duck typing,您实际上不需要声明您的 class 实现了接口。相反,您只需说明您需要什么接口,然后让编译器确定该对象是否可以满足该需求:
var MyStuff: IMyInterface;
MyStuff := TMyObject.Create as IMyInterface;
MyStuff.DoSomething;
我有一个接口(实际上是多个接口),我想这样使用:
使声明接口的单元在 dwscript 脚本中可用(如果需要)。
在用 Delphi 编写的主机应用程序中创建实现接口的对象。
以某种方式使这些接口对 dwscript 脚本可用。
并在脚本中正常使用它们。
有没有可能这样做?
我试图提供在 class 中返回这些接口的方法,但是当我在 RTTI 上使用这个 class 时,找不到那些方法。
正如我上面所说的,不能立即声明一个接口并用 TdwsUnit
实现它 Delphi 端。但是,您可以通过其他方式实现您的目标。
我假设您已经在 TdwsUnit
中声明了您的接口和 class。我们称它们为 IMyInterface
和 TMyClass
.
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;
解决方案 1 - 在 运行 时间
更改 class 声明为 TdwsUnit.OnAfterInitUnitTable
事件创建事件处理程序并将接口添加到 class 声明:
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;
现在您可以通过脚本中的接口访问 class 的实例:
var MyStuff: IMyInterface;
MyStuff := TMyObject.Create;
MyStuff.DoSomething;
解决方案 2 - 使用 duck typing
由于 DWScript 支持 duck typing,您实际上不需要声明您的 class 实现了接口。相反,您只需说明您需要什么接口,然后让编译器确定该对象是否可以满足该需求:
var MyStuff: IMyInterface;
MyStuff := TMyObject.Create as IMyInterface;
MyStuff.DoSomething;