2014-01-17 1 views
2

여러 프로젝트에 초기화 섹션이있는 프로젝트가 있습니다. 이 블록이 실행되는 순서를 제어하고 싶습니다.단위 초기화 순서가 소스에 나와 있지 않습니다.

다음에 따르면 question은 단위가 컴파일 된 순서에 기반하므로 궁극적으로 순서는 원본 DPR의 uses 절에있는 단위의 배열을 기반으로해야합니다.

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를 제공하고 싶지만 단순히 새로운 프로젝트에서이 문제를 재현 할 수는 없습니다.

나는 프로젝트를 성공 리에 재구성하려고 노력했다.

무엇이 누락 되었습니까?

+0

uMain은 uFooA 및/또는 uFooB를 사용합니까? 이 경우 사용 된 단위가 먼저 컴파일됩니다. –

+0

@UweRaabe, 아, 네, 바보 같아요 ... 받아 들일 수 있도록 답을 게시 해주세요. – Peter

+0

여기에 답변이 필요할지 모르겠습니다. 컴파일러는 DPR의 uses 절의 맨 위에서 시작하여 아래로 내려갑니다. 발견 한 각 단위에 대해 반복적으로 같은 작업을 수행합니다. 시작 부분에서 시작합니다. uses 절을 사용하여 이미 컴파일되지 않은 사용 된 각 유닛을 컴파일하고 현재 유닛을 컴파일하십시오. 그래서 다른 것들이 컴파일되기 전에 유닛을 가져올 수 있다면 먼저 초기화 될 것입니다. * –

답변

5

컴파일러가 초기화를 결정하는 엄격한 방법이 있지만 많은 의존성이있는 유닛이 많은 경우 인간이 정확하게 파악하고 제어하는 ​​것은 매우 어렵습니다.

예. 귀하의 DPR은 UnitA, UnitB, UnitC;을 사용할 수 있지만 UnitAUnitB에 종속 된 경우 먼저 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이 부족하고 많은 장치가 초기화를 필요로 혼란스러워한다. 그러나, 관리가 용이하도록 다른 기술을 적용 할 수 있습니다.