Несколько лет go Я портировал старое приложение unix на Delphi 5. Для итераций связанных списков он использовал локальные процедуры, передаваемые по адресу глобальной функции 'итератора'.
Ниже приведен упрощенный пример:
type TPerformProc = procedure;
procedure Perform(proc:TPerformProc);
begin
proc;
end;
procedure Test;
var loc_var:integer;
procedure loc_proc;
begin
loc_var:=loc_var+10;
end;
begin
loc_var:=0;
writeln('loc var: ',loc_var);
Perform(addr(loc_proc));
writeln('loc var: ',loc_var);
writeln('-----');
end;
В примере процедуры происходит сбой в Delphi, но она работает на unix просто отлично.
С некоторой помощью я смог заставить его работать так:
type TPerformProc = procedure;
var loc_bp:integer;
procedure Perform(proc:TPerformProc);
begin
asm
push loc_bp
end;
proc;
asm
pop eax
end;
end;
procedure Test;
var loc_var:integer;
procedure loc_proc;
begin
loc_var:=loc_var+10;
end;
begin
loc_var:=0;
writeln('loc var: ',loc_var);
asm
mov loc_bp,ebp
end;
Perform(addr(loc_proc));
writeln('loc var: ',loc_var);
writeln('-----');
end;
Чтобы решить проблему, я сохраняю ссылку на кадр стека локальной процедуры, а затем Я вызываю локальную процедуру.
Мне ясно, что вышеприведенное решение - это не правильное решение, а скорее взлом, и я понимаю, что новая версия Delphi может обрабатывать локальные процедуры по-другому и сломать взломать. К счастью, эта часть Delphi осталась прежней, и код работает нормально даже с последней версией Delhi.
Однако я хочу скомпилировать приложение как 64-битное, и хак больше не работает. До сих пор я не смог найти аналогичное решение, но для 64-битной. Здесь кто-то может помочь?
Спасибо.