簡體   English   中英

Delphi單元初始化並不總是被調用

[英]Delphi unit initialization not always called

我在.bpl中有一個單元,我需要一個字符串列表來表示我編寫的新函數。 我希望stringlist在應用程序的生命周期內保持不變,這樣每個調用都可以建立在之前調用的內容之上。

所以它在單元內全局聲明,我在Initialization部分初始化它,如下所示:

var
  ProductLookup : TStrings;  
...

function foo : boolean;
begin
  result := (ProductLookup.IndexOfName('bar') >=0); //blow up here. It's nil. Why?
end;
....

initialization
  ProductLookup := TStringList.Create;  // This should get run, but doesn't.

finalization
  FreeAndNil(ProductLookup);

end.

當我對它進行單元測試時,一切都很好。 但是當它從主應用程序運行時,由於字符串列表為零而導致訪問沖突。 所以現在我在foo函數中檢查nil並在必要時創建。 但我不知道為什么初始化對我不起作用。 我在初始化中放了一個調試消息,當它作為BPL加載時它不會運行,但如果我直接編譯到我的dUnit exe中,它會運行。 有任何想法嗎? Delphi2005。

達里安提醒我, 我之前已經回答過

如果操作系統在加載關聯的EXE時加載BPL,則不會調用所有初始化部分。 相反,只調用程序中其他東西顯式使用的單元中的部分。

如果初始化部分中的代碼注冊了一個類,然后您只是間接引用該類,比如通過在列表中按名稱查找它,那么可能不會調用該單元的初始化部分。 將該單元添加到程序中的任何“uses”子句應該可以解決該問題。

若要解決此問題,您可以通過在SysUtils單元中調用InitializePackage函數來自己初始化程序包的單位。 它需要一個模塊句柄,您可以通過調用GetModuleHandle API函數獲得該句柄。 該函數只調用尚未初始化的單元的初始化部分。 無論如何,這是我的觀察。

如果您調用InitializePackage ,那么您還應該調用FinalizePackage 當您的包被卸載時,將為所有自動初始化的單元調用終結部分。

如果操作系統沒有自動加載您的軟件包,那么您將使用LoadPackage函數加載它。 它會為您初始化所有包的單位,因此您無需自己調用InitializePackage 同樣, UnloadPackage將為您完成所有事情。

只在Quality Central中找到了一個參考,但可能還有更多。 包括LoadPackage引用的解決方法。

http://qc.embarcadero.com/wc/qcmain.aspx?d=61968

在某些情況下,並非BPL中的每個單元都必須初始化。 如果我不得不猜測,我會說這個BPL在加載時鏈接到你的程序而不是以后動態加載? 嘗試將您正在使用的單位的名稱放入DPR中的程序使用列表中。 那應該解決它。

你是如何加載bpl的? 您是否將它留給Delphi進行加載或是否手動加載bpl? 如果您手動加載bpl,是將它作為“直接”dll加載,還是使用LoadPackage將其加載為delphi包? 我認為要么讓vcl加載它(通過需要處理)或使用LoadPackage,初始化部分需要由vcl運行...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM