Oui, vous pouvez accéder à un sous-programme, qui est imbriqué dans un autre sous-programme (parent), du monde extérieur. Bien que ce soit un peu difficile. J'ai trouvé ce howto sur le web.
Comment passer de routine imbriquée comme paramètre de procédure (32 bits)
Delphi ne normalement supporte pas le passage des routines imbriquées comme paramètres de procédure:
// This code does not compile:
procedure testpass(p: tprocedure);
begin
p;
end;
procedure calltestpass;
procedure inner;
begin
showmessage('hello');
end;
begin
testpass(inner);
end;
La solution évidente consiste à passer l'adresse de procédure et cataloguée dans un délai testpass:
// This code compiles and runs OK
procedure testpass(p: pointer);
begin
tProcedure(p);
end;
procedure calltestpass;
procedure inner;
begin
showmessage('hello');
end;
begin
testpass(@inner);
end;
il y a, cependant, un piège dans e e exemple ci-dessus - si la routine "inner" référence une variable qui a été poussée sur la pile avant que la procédure "inner" soit appelée depuis testpass (paramètres calltestpass - s'il y en avait, ou variables locales dans calltestpass - s'il y en avait), votre système le plus probablement tombe en panne:
// This code compiles OK but generates runtime exception (could even be
// EMachineHangs :-))
procedure testpass(p: pointer);
begin
tProcedure(p);
end;
procedure calltestpass;
var msg: string;
procedure inner;
begin
msg := 'hello';
showmessage(msg);
end;
begin
testpass(@inner);
end;
la raison en est, en termes simples, que l'agencement de cadre de pile était « cassée » par l'appel à testpass de routine et de la procédure « intérieure » calcule correctement l'emplacement des paramètres et des variables locales (ne blâmez pas Delphi, s'il vous plaît). La solution de contournement consiste à définir le contexte de pile correct avant d'appeler "inner" depuis "testpass". Veuillez noter que l'optimisation est désactivée pour la routine de test - l'optimisation ne gère généralement pas très bien le code OP/assembleur mixte.
Privé est privé :) Êtes-vous à la recherche d'un moyen de le rendre public sans changer le code? – mjn
Ce n'est même pas privé, c'est interne. Il n'existe pas en dehors de la routine "parent" où il est intégré. –