Necesito ejecutar mi código después de la finalización de la unidad SysUtils.Orden de finalización de la unidad para la aplicación, compilada con paquetes de tiempo de ejecución?
he puesto mi código en la unidad separada y la incluyó por primera vez en la cláusula de usos DPR-archivo, así:
project Project1;
uses
MyUnit, // <- my separate unit
SysUtils,
Classes,
SomeOtherUnits;
procedure Test;
begin
//
end;
begin
SetProc(Test);
end.
MyUnit se ve así:
unit MyUnit;
interface
procedure SetProc(AProc: TProcedure);
implementation
var
Test: TProcedure;
procedure SetProc(AProc: TProcedure);
begin
Test := AProc;
end;
initialization
finalization
Test;
end.
Tenga en cuenta que MyUnit no tiene ningún uso.
Este es el habitual Windows exe, sin consola, sin formularios y compilado con paquetes predeterminados de tiempo de ejecución. MyUnit no es parte de ningún paquete (pero he intentado usarlo también desde el paquete).
Espero que la sección de finalización de MyUnit se ejecute después de la sección de finalización de SysUtils. Esto es lo que la ayuda de Delphi me dice.
Sin embargo, este no es siempre el caso.
Tengo 2 aplicaciones de prueba, que difieren un poco por código en Probar rutina/archivo dpr y unidades, enumeradas en los usos. MyUnit, sin embargo, aparece primero en todos los casos.
Una aplicación se ejecuta como se esperaba: Halt0 -> FinalizeUnits -> ... otras unidades ... -> finalización de SysUtils -> finalización de MyUnit -> ... otras unidades ...
Pero el segundo no es La finalización de MyUnit se invoca antes de Finalización de SysUtils. La cadena de llamadas actual se ve así: Halt0 -> FinalizeUnits -> ... otras unidades ... -> Finalización de SysUtils (omitida) -> Finalización de MyUnit -> ... otras unidades ... -> Finalización de SysUtils (ejecutada)
Ambos proyectos tienen configuraciones muy similares. Intenté eliminar/minimizar sus diferencias, pero todavía no veo una razón para este comportamiento.
He intentado depurar esto y descubrí que: parece que cada unidad tiene algún tipo de recuento de referencias. Y parece que InitTable contiene múltiples referencias a la misma unidad. Cuando se llama a la sección de finalización de SysUtils por primera vez, cambia el contador de referencia y no hace nada. Luego se ejecuta la finalización de MyUnit. Y luego SysUtils se llama de nuevo, pero esta vez ref-cuenta llega a cero y sección de finalización se ejecuta:
Finalization: // SysUtils' finalization
5003B3F0 55 push ebp // here and below is some form of stub
5003B3F1 8BEC mov ebp,esp
5003B3F3 33C0 xor eax,eax
5003B3F5 55 push ebp
5003B3F6 688EB50350 push $5003b58e
5003B3FB 64FF30 push dword ptr fs:[eax]
5003B3FE 648920 mov fs:[eax],esp
5003B401 FF05DCAD1150 inc dword ptr [$5011addc] // here: some sort of reference counter
5003B407 0F8573010000 jnz $5003b580 // <- this jump skips execution of finalization for first call
5003B40D B8CC4D0350 mov eax,$50034dcc // here and below is actual SysUtils' finalization section
...
Puede alguien puede triturar luz sobre esta cuestión? ¿Me estoy perdiendo de algo?
> ¿Hay alguna razón en particular por su MyUnit necesita para finalizar después SysUtils? Sí. Son cheques que pierden memoria. – Alex
@Alexander: ¿Se está haciendo algo especial que no se puede obtener con FastMM en FullDebugMode? –
> ¿Está haciendo algo especial que no puede obtener con FastMM en FullDebugMode? Esa no es la pregunta, que estoy preguntando, así que dejémosla a un lado. FastMM no funcionó en mi segunda aplicación exactamente por la misma razón: se llama demasiado pronto. – Alex