在程序執行的時候,我們可以通過vIEw|debug window|moudles來查看有哪些 東西被加載到內存中去了,它們又包含哪些內容。簡便起見,我們建立如下結構 的一個程序:
program ProjectEXE;
uses
Forms,
Windows,
UnitFormMain in 'UnitFormMain.pas' {FormMain};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TFormMain, FormMain);
Application.Run;
end.
unit UnitFormMain;
interface
uses
Windows, StdCtrls, Forms, UnitFormAnother,Classes, Controls;
type
TFormMain = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
{$R *.dfm}
procedure TFormMain.Button1Click(Sender: TObject);
var
LForm:TFormAnother;
begin
LForm:=TFormAnother.Create(Application);
LForm.ShowModal;
LForm.Free;
end;
end.
unit UnitFormAnother;
interface
uses
Forms;
type
TFormAnother = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
implementation
{$R *.dfm}
end.
“Build with runtime packages”不打鉤的時候,是靜態連接的。有向圖中 出現的所有Unit都包含在目標文件中了,整個exe有356k,而兩個Unit各自只有 4k。
現在來動態。“Build with runtime packages”打鉤,現在發現運行時 ProjectEXE.exe文件只包含四個部分:兩個Form、一個SysInit.pas、一個 ProjectEXE.dpr;與此同時進程樹裡面多了兩個bpl:rtl60和vcl60,它們的內 容就是剛才靜態連接中出現的那些Unit。現在ProjectEXE.exe只有16k。也就是 說,有向圖中的Unit,一部分放在exe中了,另一部分放在bpl中了。但是根據什 麼來劃分呢?是根據uses子句,還是根據這裡“Build with runtime packages ”中的列表?繼續測試,發現:如果列表中僅包含vcl60,則加載到內存中的還 是兩個bpl加一個exe;如果列表中只包含rtl60,則內存中僅包含rtl60和exe, 但是exe的內容發生了變化:裡面的Unit增多了,而且基本都是vcl60包裡面的。我猜想應該是rtl和vcl包之間存在require關系。這個留到下一步再測試。但是 初步估計連接過程中,肯定會利用包列表,將那些已經在包中存在的Unit從exe 中排除出去。
在動態連接之後,還存在一個問題:裝入。裝入有兩種策略,靜態也稱為自 動,由delphi生成代碼,在裝載exe之前,自動裝入包;另一種是動態,即在程 序運行時通過編碼,指定一個包,把它裝入內存。問題在於,我必須搞清楚 delphi在什麼情況下會自動裝入一個包,什麼情況下可以避免Delphi自作聰明, 這樣才能靈活地使用包。前面的試驗中,只可以看出,在dpr文件執行到begin之 前,靜態連接的的包就已經裝入內存了。具體過程我也不清楚,等下一章開始寫 自己的包,再來做實驗吧。