delphi - 使用 Delphi XE3 64 位的嵌套比较器函数 TStringList.CustomSort 失败

标签 delphi nested compare delphi-xe3 tstringlist

我有这个简单的代码

procedure TForm2.btn1Click(Sender: TObject);
var s : TStringList;

  function compare(s : TStringList; i1, i2 : integer) : integer;
  begin
    result := CompareText(s[i1], s[i2]);
  end;

begin
  s := TStringList.Create;
  try
    s.add('s1');
    s.add('s2');
    s.add('s3');
    s.CustomSort(@compare);
  finally
    s.free;
  end;
end;

当我将其编译为 32 位时,它可以按预期工作,但是当使用 64 位时,我会遇到访问冲突。 对于函数比较中的 64 位版本,s = nil. i2 = some random value ;

如果我提取compare,即使对于Win64目标,它也能按预期工作。 btn1Click 之外的函数功能。

是否是System.Classes的bug,有什么办法修复吗?

最佳答案

局部嵌套函数不应该分配给过程变量(特别是不应该作为过程变量参数传递)。

http://docwiki.embarcadero.com/RADStudio/XE4/en/Procedural_Types - 搜索“嵌套”。

原因很简单:本地函数应该安排它们的堆栈,以便它们可以访问所有上层函数(父级)堆栈帧。然而,当这些函数在没有事先一一调用其父函数的所有链的情况下跳转到这些函数时,这些堆栈帧就不可能存在。当将他们的地址传递给不知道这个特定调用链的高管时,就会发生这种“突然”的跳水。这就像在没有 VMT 链接到父类并且没有 Self 指向正确的 VMT 的情况下调用某个对象的虚拟方法。

问题并不是这样的代码在 win64 中不起作用。

错误在于它甚至可以在 win32 或 win64 中编译。

当 Delphi 修复该错误时,它不会再编译这样的代码,除非您将 compare 设为适当的全局函数,就像它应该的那样。

关于delphi - 使用 Delphi XE3 64 位的嵌套比较器函数 TStringList.CustomSort 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17783302/

相关文章:

delphi - 将 QuickReport 转换为 FastReport

arrays - 重命名 TValue 数组类型

json - 使用 scala 提取嵌套的 JSON 元素

python - 我可以比较两个顺序不同的字典的键吗?

algorithm - 根据姓名、DoB、地址等匹配人员

java - 有效的方法。 Java中比较列表元素的方法

Delphi XE2 DataSnap - 通过 TStream 将 JPEG 文件从服务器流式传输到客户端

delphi - 如何确定 DBGrid 是否处于插入模式

python - 将嵌套列表转换为 pd Dataframe 的快速且 Pythonic 的方法

iphone - 嵌套 UITableView : a way to scroll both the outer vertical UITableView and a child horizontal UITableView at the same time?