如何将接口对象传递给Pascal Script函数调用? [英] How to pass the interfaced object to the Pascal Script function call?

查看:142
本文介绍了如何将接口对象传递给Pascal Script函数调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Delphi部分:

Delphi part:

我有一个与该事件有关的课程,从该事件中我需要致电将接口对象传递给它的过程。它在Delphi中工作正常,但是在Pascal Script中声明它时遇到了问题。

I have a class with the event and from that event I need to call a procedure passing the interfaced object to it. It works fine in Delphi but I have problems with declaring it in Pascal Script.

对于后台- IGPGraphics 界面是 Delphi GDI +库 且没有方法的定义如下:

To the background - the IGPGraphics interface is a part of the Delphi GDI+ library and without methods is defined like this:

type
  IGdiplusBase = interface
  ['{24A5D3F5-4A9B-42A2-9F60-20825E2740F5}']
  IGPGraphics = interface(IGdiPlusBase)
  ['{57F85BA4-CB01-4466-8441-948D03588F54}']

The以下只是我需要在Pascal脚本中执行的简化的Delphi伪代码:

The following is just a simplified Delphi pseudocode of what I need to do in Pascal Script:

type
  TRenderEvent = procedure(Sender: TObject; const GPGraphics: IGPGraphics) of object;
  TRenderClass = class(TGraphicControl)
  private
    FOnRender: TRenderEvent;
  public
    property OnRender: TRenderEvent read FOnRender write FOnRender;
  end;

// when the TRenderClass object instance fires its OnRender event I want to call 
// the RenderObject procedure passing the IGPGraphics interfaced object to it; I
// hope I'm doing it right, I'm just a newbie to this stuff - but it works so far
// in Delphi (since I didn't get it to work in Pascal Script)

procedure TForm1.RenderClass1Render(Sender: TObject; const GPGraphics: IGPGraphics);
begin
  RenderObject(GPGraphics, 10, 10);
end;

// what I need in Pascal Script is between these two lines; just pass the interface
// object from the event fired by component to the procedure called from inside it

procedure RenderObject(const GPGraphics: IGPGraphics; X, Y);
begin
  // and here to work with the interfaced object somehow
end;

Pascal脚本编译部分:

Pascal Script compilation part:

我的目标是使带有事件的类在Pascal脚本中可用,并且需要像上面那样将接口对象传递给该过程,因此,我首先尝试声明编译时间(但我什至不知道这样做是否正确):

My aim is to have the class with event available in Pascal Script and need to pass that interfaced object to that procedure just like above, so the first I've tried to declare for the compilation time this (but I'm not even sure if that's the right way to do so):

// the interface
PS.AddInterface(Cl.FindInterface('IUnknown'), StringToGuid('{57F85BA4-CB01-4466-8441-948D03588F54}'), 'IGPGraphics');
// the type for the event
PS.AddTypeS('TRenderEvent', 'procedure(Sender: TObject; const GPGraphics: IGPGraphics)');
// and the class with the event itself
with PS.AddClassN(PS.FindClass('TGraphicControl'), 'TRenderClass') do
begin
  RegisterProperty('OnRender', 'TRenderEvent', iptrw);
end;

Pascal脚本运行时部分:

Pascal Script runtime part:

我绝对迷失的地方是运行时部分。我不知道如何从调用堆栈中获取接口对象并将其传递给我的RenderObject过程:

Where I'm definitely lost is the runtime part. I can't figure out how to get the interfaced object from the call stack and pass it to my RenderObject procedure:

function RenderClassProc(Caller: TPSExec; Proc: TPSExternalProcRec; Global, 
  Stack: TPSStack): Boolean;
var
  PStart: Cardinal;
begin
  PStart := Stack.Count-1;
  Result := True;
  if Proc.Name = 'RENDEROBJECT' then
  begin
    // how do I get the interfaced object from Stack (or whatever else) and pass 
    // it to the RenderObject proc here ? I can't find anything related about it
    // except functions that has no parameter index
    RenderObject(Stack.Get ?, Stack.GetInt(PStart-2), Stack.GetInt(PStart-3));
  end;
end;

问题是:

And the question is:

有人可以建议我如何为此情况正确定义编译和运行时部分,或者通过某种方式传递接口对象来纠正我吗?

Can anyone suggest me how to correctly define compilation and runtime part for this case or correct me with passing the interfaced object somehow ?

PS对于该Inno-Setup标签感到抱歉,但也许某人从那里尝试通过这种方式自定义InnoSetup。

P.S. sorry for that Inno-Setup tag but maybe someone from there tried to customize InnoSetup this way.

非常感谢!

推荐答案

如果我理解您的要求,则希望将接口作为参数传递给方法。不幸的是,我没有确切的答案,但是我知道如何为PascalScript的全局变量分配接口。以下是我在Castalia中的操作方法:

If I understand what you're asking, you want to pass an interface as a parameter to a method. Unfortunately, I don't have an exact answer to that, but I do know how to assign an interface to a global variable for PascalScript. Here's how I do it in Castalia:

在PSScript OnCompile事件中,使用PS.Comp.AddInterface添加接口,然后添加每个必要的方法。之后,添加接口类型的变量。看起来像这样,例如:

In the PSScript OnCompile event, add the interface with PS.Comp.AddInterface, and then add each of the necessary methods. After that, add a variable of the interface type. It looks like this, for example:

with PS.Comp.AddInterface(ARunner.Comp.FindInterface('IUnknown'),
  StringToGUID('{0346F7DF-CA7B-4B15-AEC9-2BDD680EE7AD}'),
  'ICastaliaMacroClipboardAccess') do
begin
  RegisterMethod('function GetText: string', cdRegister);
  RegisterMethod('procedure SetText(AText: string)', cdRegister);
end;
PS.AddRegisteredVariable('Clipboard', 'ICastaliaMacroClipboardAccess');

然后,在OnExectute事件中,将先前创建的变量绑定到实例:

Then, in the OnExectute event, bind the previously created variable to the instance:

P := PS.GetVariable('Clipboard'); //P is type PIFVariant
SetVariantToInterface(P, Implementing object as ICastaliaMacroClipboardAccess);    

这样做,脚本可以通过变量访问接口对象,因此在这种情况下,该脚本可能包含对Clipboard.GetText的调用,它可以按您期望的那样工作。

Having done that, the script has access to the interfaced object through the variable, so in this instance, the script could contain a call to Clipboard.GetText, and it works as you would expect.

经过测试并且可以工作。

That is tested and works.

现在,我推测您可能可以使用TPSScript.ExecuteFunction从上方传入PIFVariant,以更接近您想要的内容。

Now, I would speculate that you might be able to use TPSScript.ExecuteFunction, passing in the PIFVariant from above, to get closer to what you want. That is not something I've tested, however.

祝你好运!

这篇关于如何将接口对象传递给Pascal Script函数调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆