Delphi 单元初始化顺序与源代码中的指示不符
我有一个项目,其中多个单元有初始化部分。我想控制执行这些块的顺序 根据以下内容,这是基于单元的编译顺序,因此最终顺序应基于源DPR的uses子句中的单元安排 以下是我项目的DPR来源:Delphi 单元初始化顺序与源代码中的指示不符,delphi,delphi-xe4,Delphi,Delphi Xe4,我有一个项目,其中多个单元有初始化部分。我想控制执行这些块的顺序 根据以下内容,这是基于单元的编译顺序,因此最终顺序应基于源DPR的uses子句中的单元安排 以下是我项目的DPR来源: program X; uses Vcl.Forms, uMain in 'uMain.pas' {MainForm}, uFooA in 'uFooA.pas', uFooB in 'uFooB.pas'; {$R *.res} begin Application.Initialize;
program X;
uses
Vcl.Forms,
uMain in 'uMain.pas' {MainForm},
uFooA in 'uFooA.pas',
uFooB in 'uFooB.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.
我的问题是,这根本不是执行初始化块的顺序
How it should be | How it actually is
|
1. uMain | 1.uFooA
2. uFooA | 2.uFooB
3. uFooB | 3.uMain
我很想提供一个SSCCE,但我无法在一个新的项目上重新制作这个问题
我试图重建这个项目,但没有成功
我遗漏了什么?尽管编译器有一种严格的方式来确定初始化,但对于一个人来说,当有许多具有许多依赖关系的单元时,很难准确地判断和控制 例如,您的DPR可以使用
UnitA、UnitB、UnitC代码>但如果UnitA
依赖于UnitB
,则必须首先初始化UnitB
诚然,具有初始化和终结部分的单元的特性可以使添加功能变得像“添加单元”一样简单。虽然这看起来很好,但实际上,在真正大型的项目中,它往往会成为阻碍。就我个人而言,我认为“特征”相当可怕。
控制机组优化顺序的最佳和最可靠的方法是明确地这样做。例如
program X;
uses
Vcl.Forms,
uMain in 'uMain.pas' {MainForm},
uFooA in 'uFooA.pas',
uFooB in 'uFooB.pas';
{$R *.res}
begin
Init_uMain;
Init_uFooA;
Init_uFooB;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
Finalise_uFooB;
Finalise_uFooA;
Finalise_uMain;
end.
显然,上面的代码缺少适当的try..finallys,并且会因为许多单元需要初始化而变得混乱。然而,还有其他技术可以用来保持事情的可管理性。uMain是否使用uFooA和/或uFooB?在这种情况下,使用的单位首先被编译。@Uwerabe,啊,是的,它们是,愚蠢的我。。。请发布一个答案,以便我可以接受。我不确定这里是否需要答案。Mason在你链接到的答案中的解释说明了一切:编译器从DPR的uses子句的顶部开始向下运行,对于找到的每个单元,它递归地执行相同的操作:从uses子句的开头开始,尝试编译每个未编译的已用单元,然后编译当前单元。因此,如果您能在编译其他任何单元之前将单元导入,那么它将首先初始化。@DavidHeffernan,感谢您指出这一点,我已经阅读了它,但我跳过了最重要的部分:s