我需要在完成 SysUtils 单元后执行我的代码。
我已将代码放在单独的单元中,并将其首先包含在 dpr 文件的 uses 子句中,如下所示:
project Project1;
uses
MyUnit, // <- my separate unit
SysUtils,
Classes,
SomeOtherUnits;
procedure Test;
begin
//
end;
begin
SetProc(Test);
end.
MyUnit 看起来像这样:
unit MyUnit;
interface
procedure SetProc(AProc: TProcedure);
implementation
var
Test: TProcedure;
procedure SetProc(AProc: TProcedure);
begin
Test := AProc;
end;
initialization
finalization
Test;
end.
请注意,MyUnit 没有任何用途。
这是通常的 Windows exe,没有控制台,没有表单,并使用默认运行时包编译。MyUnit 不是任何包的一部分(但我也尝试从包中使用它)。
我希望 MyUnit 的最终化部分将在 SysUtils 的最终化部分之后执行。这是德尔福的帮助告诉我的。
然而,这并非总是如此。
我有 2 个测试应用程序,它们在使用中列出的测试例程/dpr 文件和单元中的代码略有不同。然而,MyUnit 在所有情况下都排在首位。
一个应用程序按预期运行:Halt0 -> FinalizeUnits -> ...其他单元... -> SysUtils's finalization -> MyUnit's finalization -> ...其他单元...
但第二个不是。MyUnit 的终结在 SysUtils 的终结之前被调用。实际的调用链如下所示:Halt0 -> FinalizeUnits -> ...其他单元... -> SysUtils 的完成(跳过) -> MyUnit 的完成 -> ...其他单元... -> SysUtils 的完成(执行)
这两个项目的设置非常相似。我尝试了很多来消除/最小化它们的差异,但我仍然看不出这种行为的原因。
我尝试对此进行调试并发现:似乎每个单元都有某种引用计数。似乎 InitTable 包含对同一单元的多次引用。当 SysUtils 的 finalization 部分第一次被调用时——它改变了引用计数器并且什么都不做。然后执行 MyUnit 的 finalization。然后再次调用 SysUtils,但这次 ref-count 达到零并执行 finalization 部分:
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
...
任何人都可以解决这个问题吗?我错过了什么吗?