delphi - 使用回调访问 voilation delphi x64
问题描述
我在新标准(x64,Rad Studio XE 10.4)上重写了旧代码(x86 ~ 1998 年,delphi 7)。我找到了问题的地方,这停止了我的工作。我创建了一个最小的例子,你可以调试(代码的结构严格来说是这样的!):
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, ShellApi;
type
TTestProc = procedure(btn: TButton; i: Integer);
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure KeyDownTest();
function FindNewFocused(): boolean;
procedure Iterate(IterateProc: TTestProc);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
KeyDownTest(); // --> KeyDownTest
end;
procedure TForm1.KeyDownTest();
begin
FindNewFocused(); // --> FindNewFocused
end;
function TForm1.FindNewFocused(): boolean;
procedure IntNextVis(btn: TButton; i: Integer);
begin
ShowMessage(btn.Caption); // ----> ERROR: ACCESS VOILATION!
end;
begin
Iterate(@IntNextVis); // --> Iterate
Result := True;
end;
procedure TForm1.Iterate(IterateProc: TTestProc);
procedure IntIterate(btn: TButton; i: Integer);
begin
if(i > 2) then
Exit; // --> break reqursive
if(i = 2) then
IterateProc(btn, i) // --> FindNewFocused.IntNextVis
else
IntIterate(btn, i + 1); // --> Iterate.IntIterate
end;
var
i: Integer;
begin
i := 0;
//ShowMessage(Button1.Caption); // ----> WORKING!
IntIterate(Button1, i); // --> Iterate.IntIterate
end;
end.
在表格上有一个按钮,按下该按钮在屏幕上将写下消息,例如:标题按钮。此代码在 x86 平台上正常工作,但在 x64 平台上损坏。我查看调试器、堆栈跟踪和反汇编程序(x64 平台!)并发现错误:当应用程序调用回调过程时IntNextVis(btn: TButton; i: Integer);
,然后在 asm 代码中首先传输 args 回调,然后删除!因此, callShowMessage(btn.Caption);
是不正确的,因为 btn 将被删除。我目前的配置Debug
。为什么会这样以及如何修复这个错误?PS:请告诉我在不IntNextVis
从全局可见性区域移动局部可见性区域的程序的情况下解决这个问题,就像在我的旧代码中非常非常非常马赫这样的代码一样。