This question already has an answer here:
Why cannot take address to a nested local function in 64 bit Delphi?

(1个答案)


3年前关闭。




我们有一些使用Contnrs.TObjectList的旧类,并且在某些情况下,使用自定义比较功能对这些列表进行排序,如下所示:
procedure TMyClass.SortItems;

  function CompareFunction(Item1, Item2: Pointer): Integer;
  begin
    Result := TSomeItem(Item1).Value - TSomeItem(Item2).Value;
  end;

begin
  Sort(@CompareFunction);
end;

在为Win32编译时,此代码可以正常工作,但是在为Win64编译时,我们发现排序不再起作用。

我通过改用Generics.Collections.TObjectList<T>并修改了CompareFunction及其调用方式来修复了其中的一些问题。所以我的猜测是,它与CompareFunction的调用方式有关,在它前面加上了@运算符,据我所知,该运算符指向函数的地址。

为什么上面的代码在Win64上不起作用,什么是修复它的正确方法?

最佳答案

TObjectList.Sort()的回调函数需要一个独立的函数。

内部函数共享其父函数的堆栈框架(因此它可以访问父函数的局部变量和参数)。因此,您不能使用内部函数作为回调。由于32位函数的运行方式fl幸,因此您无法使用32位。但这在64bit中将不再起作用。

您需要自行移出CompareFunction(),例如:

function CompareFunction(Item1, Item2: Pointer): Integer;
begin
  Result := TSomeItem(Item1).Value - TSomeItem(Item2).Value;
end;

procedure TMyClass.SortItems;
begin
  Sort(@CompareFunction);
end;

这将适用于32位和64位。

10-05 22:40