¿Orden de finalización de la unidad para la aplicación, compilada con paquetes de tiempo de ejecución?

Necesito ejecutar mi código después de finalizar la unidad SysUtils.

Coloqué mi código en una unidad separada y lo incluí primero en la cláusula de usos del archivo dpr, 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.

Esto es habitual en Windows exe, sin consola, sin formularios y compilado con paquetes de tiempo de ejecución predeterminados. MyUnit no forma parte de ningún paquete (pero también he intentado usarlo 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 me dice la ayuda de Delphi.

Sin embargo, este no es siempre el caso.

Tengo 2 aplicaciones de prueba, que difieren un poco por código en Prueba de 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 lo es. Se invoca la finalización de MyUnitantes de Finalización de SysUtils. La cadena de llamadas real 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é mucho eliminar / minimizar sus diferencias, pero aún no veo una razón para este comportamiento.

Intenté depurar esto y descubrí que: parece que cada unidad tiene algún tipo de recuento de referencias. Y parece que InitTable contiene referencias de multiplicación a la misma unidad. Cuando la sección de finalización de SysUtils se llama por primera vez, cambia el contador de referencia y no hace nada. Luego se ejecuta la finalización de MyUnit. Y luego se llama nuevamente a SysUtils, pero esta vez el recuento de ref llega a cero y se ejecuta la sección de finalización:

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
...

¿Alguien puede arrojar luz sobre este tema? ¿Me estoy perdiendo de algo?

Respuestas a la pregunta(4)

Su respuesta a la pregunta