Delphi 指向(子)方法的函数的指针?

Delphi 指向(子)方法的函数的指针?,delphi,pointers,delphi-7,Delphi,Pointers,Delphi 7,如果您想使用方法的指针作为参数,则需要键入方法作为对象的函数这样做很好: type TAcceptor = function(filename:string):boolean of object; function acceptor(filename:string):boolean; begin result := filename <> ''; end; procedure TForm1.Button1Click(Sender:TObject); function

如果您想使用方法的指针作为参数,则需要
键入
方法作为对象的
函数
这样做很好

type TAcceptor = function(filename:string):boolean of object;
function acceptor(filename:string):boolean; 
begin 
  result := filename <> ''; 
end;
procedure TForm1.Button1Click(Sender:TObject);
  function acceptor(filename:string):boolean of object;
  begin 
    result := filename <> ''; 
  end;
begin
end;
type TAcceptor=function(文件名:string):对象的布尔值;
函数接受器(文件名:字符串):布尔值;
开始
结果:=文件名“”;
结束;
如果您想使用子方法的指针,该怎么办?它不工作:

type TAcceptor = function(filename:string):boolean of object;
function acceptor(filename:string):boolean; 
begin 
  result := filename <> ''; 
end;
procedure TForm1.Button1Click(Sender:TObject);
  function acceptor(filename:string):boolean of object;
  begin 
    result := filename <> ''; 
  end;
begin
end;
procedure TForm1.按钮1点击(发送方:TObject);
函数接受器(文件名:字符串):对象的布尔值;
开始
结果:=文件名“”;
结束;
开始
结束;
错误occour:
;应为,但已找到


问题:是否有任何子函数指针?我能投吗?

我不知道这怎么可能

如果您在该部分下查看,它特别指出不能使用嵌套的过程和函数:

嵌套过程和函数(在其他程序中声明的例程 例程)不能用作过程值,也不能预定义 程序和职能。”

您可以使用匿名方法来解决此问题。比如:

procedure TForm1.Button1Click(Sender:TObject);
begin
  DoSomethingWithAcceptor(function(FileName: string): Boolean
  begin 
    Result := FileName <> '';
  end);
end;
procedure TForm1.按钮1点击(发送方:TObject);
开始
DoSomethingWithAcceptor(函数(文件名:字符串):布尔值
开始
结果:=文件名“”;
(完),;
结束;
注意事项 我知道以下内容并不普遍适用,但它适用于所有已知的Win32版本的Delphi。只要你知道这一点,并在新版本中检查它的功能,它是一个可行的黑客,IMO


将嵌套函数传递给方法 在较旧的代码中,我使用它来执行一些“穷人的匿名方法”:

为了在方法中填充这样一个局部函数,我编写了函数local:

function Local(LocalFunction: Pointer): TLocal;
asm
  MOV [EDX].TLocal.Frame,EBP
  MOV [EDX].TLocal.Code,EAX
end;
在我的单元(某种泛型集合)中,我编写了一个函数来调用它们,传递一个参数(类型为TGeneric,在本例中,这在这里并不重要,您还可以传递一个指针或类似的参数)

它是这样使用的:

function TStdCollection.AsArray: TGenericArray;
var
  I: Integer;
  A: TGenericArray;

  procedure ToArray(E: TGeneric);
  begin
    Result[I] := E.Traits.Copy(E);
    Inc(I);
  end;

begin
  SetLength(A, Count);
  I := 0;
  ForEach(Local(@ToArray));
  Assert(I = Count);
  Result := A;
end;
嵌套函数中的代码生成元素的副本并将其存储在数组中。然后,主过程将嵌套函数ToArray(及其堆栈帧)作为参数传递给ForEach,其实现方式如下:

function TStdCollection.ForEach(Operation: TLocal): ICollection;
var
  Enum: IEnumerator;
  Elem: TGeneric;
begin
  Enum := GetEnumerator;
  Elem := Enum.First;
  while Elem <> nil do
  begin
    CallLocal(Elem, Operation);
    Elem := Enum.Next;
  end;
  Result := Self;
end;
函数TStdCollection.ForEach(操作:TLocal):ICollection;
变量
枚举:IEnumerator;
元素:TGeneric;
开始
枚举:=GetEnumerator;
元素:=Enum.First;
而Elem nil do
开始
CallLocal(元素,操作);
元素:=Enum.Next;
结束;
结果:=自我;
结束;
这些例子展示了如何使用局部变量。我希望这或多或少能回答你的问题


请注意,此代码是在Delphi6时间框架内编写的。我知道现在有更好的替代方法,比如泛型和匿名方法。但是,如果需要与Delphi 7兼容,以上可能是一个解决方案。

您所问的代码无法编译。您不能在函数定义中写入对象的名称。@DavidHeffernan您是对的,我更新了代码。确保出现错误是因为语法错误;要么代码示例与所问问题无关,要么我不明白实际问的是什么。请参阅。@user246408 David不是指2.snipplet,而是指1.snipplet,我编写的第一个snipplet
运行良好
无效。检查编辑历史记录以了解1.snipplet无法工作的原因。David很清楚2.snipplet只用于了解我尝试做的事情,他也明白2.snipplet从未声称是可编译的。+1这是正确的。碰巧x86下的嵌套函数(不使用包含参数/变量)可以成功获取其地址。但正如文件所说,这样做是错误的。当代码在x64下编译时,鸡就要自食其果了。为了兼容性,我将代码限制为Delphi7,这太糟糕了。无论如何,你的答案看起来是正确的。我想我将采用第一行,有一种方法可以模拟它(使用嵌套的proc)。我以前做过,它是在Turbo Vision中作为一种“穷人的匿名方法”完成的。如果我能找到我的代码,我会尝试发布它。@Rudy任何这种嵌套函数的使用都依赖于实现细节,并且对于编译器更改该细节并不健壮,正如前面多次讨论的那样。正如我所说的,它自Delphi 2以来一直没有更改,因此在许多版本中都是不变的。问题是关于Delphi7,它是一个特殊的版本。这个细节会改变吗?对Kylix有效,但对Kylix无效。不,对Kylix无效。我已经提到了Win32。顺便说一句,我不知道还有人在使用Kylix。我是恐龙咆哮者