1

我正在编写一个应该能够显示任何数据列表的控件。我想要做的是模仿 for-in 构造,因为我检查包含 Current 属性和 MoveNext 方法的公共 GetEnumerator 函数。

我已确定以下内容:

  1. 我可以通过简单地在我的对象上调用 MethodAddress 来检查方法的存在。如果我得到地址,则该方法存在。
  2. 我可以使用 RTTI 来检查方法的返回类型。
  3. 我可以使用 RTTI 来检查属性并读取它。

不过,在这两者之间,我缺少一些信息:

  1. 给定地址,我如何调用该方法?我只是写一个定义(就像我会为导入一样),转换地址并调用它吗?
  2. 检查方法的返回类型需要使用其 PTypeInfo 调用 GetTypeData。我通过在类型上调用 TypeInfo 来获取 PTypeInfo。那么我如何获得给定方法的 PTypeInfo,只给定它的地址呢?
4

2 回答 2

2
  1. 要调用该方法,您需要将返回的地址放入 TMethod 的代码指针中。将对象放入 Data 指针中,然后将其转换为具有正确签名的方法指针。
  2. 要分析函数的签名,您需要一些相当复杂的 RTTI。有关详细信息,请参阅http://hallvards.blogspot.com/2006/05/hack-10-getting-parameters-of.html。但请注意底部的警告:

请注意,这仅在实例(或其组件之一)还具有指向已发布方法的已发布属性时才有效。好消息是大多数现有的已发布方法都是这种情况——例如 TForm 实例上的事件处理程序。坏消息是,我们希望在运行时动态调用的任何已发布方法都不是这种情况(因此不会分配给任何事件)。

因此,在当前的 RTTI 模型下,您尝试做的事情可能无法实现。但是 Delphi 2010 应该有一个扩展的 RTTI 系统,它可以让你更容易地做这样的事情,而且它应该是 RSN。(曾经在 Embarcadero 的网站上有一个发布倒计时,该倒计时是今晚午夜的倒计时。不过,他们已经取消了,所以我不确定这是否仍然是正式发布日期。)

于 2009-08-24T13:02:43.113 回答
1

首先,请注意 RTTI 仅适用于已发布的属性和方法。

要调用 MethodAdress 检索的方法,只需执行以下操作:

TMyMethod = procedure (Self : TObject; const Param : String);
...
var
  MyMethod : TMyMethod;
...
MyMethod := Obj.MethodAdress ('MethodName');
if Assigned (MyMethod) then
  MyMethod (Obj, 'Hallo');

关于你的第二个问题,这可能会有所帮助:

关联

于 2009-08-24T09:47:58.523 回答