TProc和引用的内部(内存)表示方式

5
有没有人知道Delphi如何表示对过程的引用?
例如:
var
  proc: TProc;
...
proc = procedure begin beep end;

我们在“proc”中有什么?

我知道对于“方法变量”,内存表示为4个字节的“过程地址”,后跟4个字节的“对象地址”,但是对于“过程引用”则略有不同,我无法完全理解。

我想要这个信息是因为我有一些旧代码,我想让它能够使用引用。

有人知道相关信息吗?


1
http://alex.ciobanu.org/?p=27 - Robert Love
2
通常,“引用过程”保存在特殊的编译器生成的接口变量中。这确保它是引用计数的,因此当没有引用时,捕获的变量可以被清理掉。您不需要知道如何实现“引用”才能使用它。这就是为什么您有一个编译器。 - David Heffernan
1个回答

10

方法引用被实现为一个COM风格的接口,其中包含一个名为Invoke的单一方法,该方法与方法引用具有相同的签名。

因此,TProc看起来像这样:

type
  TProc = interface(IInterface) // so inherits QI, AddRef, Release
     procedure Invoke;
  end;

这是一个合理的问题,因为Delphi与C++产品具有互操作性。通过使用现有的引用计数类型和惯例(COM生存期规则),可以在方法引用级别与C++进行交互。

匿名方法会生成一个隐藏类,该类实现了一个等同于方法引用接口的同型接口,即具有完全相同的形状,但不具有相同的符号标识。隐藏类不直接实现方法引用接口,因为它可能需要多次实现接口(单个块可能包含多个分配给相同方法引用类型位置的匿名方法)。


1
@Barry:一如既往的有趣!我不得不读几遍最后一段,但我想我明白了。这可能是一个愚蠢的问题,但是:括号中的部分是否意味着隐藏类的一个实例被创建来实现多个匿名方法,其中几个都在同一个普通过程(或同一个其他作用域)中定义?听起来...很复杂 :) - David
2
@David 匿名方法可以捕获本地变量;当您有多个捕获相同变量的匿名方法时,它们需要共享状态。Delphi的实现将所有与匿名方法相关联的状态(即捕获的变量)放入一个块中,并将每个匿名方法转换为该对象类上的方法,而每个捕获的变量则转换为字段。 - Barry Kelly
1
@Barry:谢谢!我没意识到分享状态是重点,我一直在想在一个对象中保留许多单独的状态(每个方法一个集合,只是使用一个对象......可能是出于某种开销原因?)听起来很混乱。现在更有意义了 :) - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接