DLL 應用 - 設計可抽換的模組(5)
2008-04-09 04:28:15来源:互联网 阅读 ()
inherited Destroy;
end;
function TPlugin.CreateForm(hMainForm: THandle): THandle;
begin
if FForm = nil then
begin
Assert(g_ConcreteClass <> nil, ''''未設定欲實體化的 Form 類別名稱!'''');
FForm := g_ConcreteClass.Create(Application);
FForm.MainFormHandle := hMainForm;
end;
Result := FForm.Handle;
end;
procedure TPlugin.DestroyForm;
begin
if FForm <> nil then
begin
FForm.Release;
FForm := nil;
end;
Application.ProcessMessages;
end;
function TPlugin.ShowModalForm: Integer;
begin
if FForm = nil then
raise Exception.Create(''''DllExoprt: 視窗尚未建立!'''');
Result := FForm.ShowModal;
end;
initialization
g_DllAppHandle := Application.Handle;
end.
範例程式
範例程式可以按此處下載:PluginDLL.zip
下載壓縮檔並解開後,請先閱讀其中的 readme.txt。
可改進之處
你可以試著修改範例程式並強化它,使它可以當作實際開發專案的基礎框架,以下列出幾項可能的改進之處:
- 賦予 TBaseForm 基本的資料處理能力,像是新增、修改、刪除...等。
- 修改使之適用於 modeless form 及 MDI 應用程式。這意味著釋放 DLL 的時機也會改變,你可能會需要一個串列結構將載入的 DLL 記錄起來,通常一個 TStringList 就可以做到。
- 讓一個 plugin 物件可以建立並維護多個不同類型的 Form 物件。
你可能會希望一個 DLL 裡面可以提供多種 form 物件供主程式使用,這些 form 物件之間可能有某種程度的相似或相依關係。根據此需求我們可以整理出 plugin 物件具備以下兩個特性:
- plugin 物件可以建立多種不同類型的 form 物件,而它們都是繼承自基礎的表單類別 TBaseForm。
- 一個 DLL 裡面只需要一個 plugin 物件。
根據 [GHJV95] 書中的定義,Abstract Factory 的用意是:
「提供一個介面來建立同一族系或相依的物件,而毋須指明它們的具象類別(concrete class)」
而 Factory 通常也被實作成 Singleton,這些特性清楚地告訴我們 plugin 物件非常適合實作成一個 Factory。你可能需要在 TPlugin 類別裡面提供一個 RegisterClass 方法,這個方法取代了原先的類別參考型態,原本在 TBaseForm 子類別的單元裡設定 g_ConcreteClass 的敘述將會改成:
PluginFactory.RegisterClass(TForm1);註冊過的類別資訊將會被記錄在一個串列裡面。主程式則可以在建立 form 物件時透過字串來指定要建立的 form 類別名稱,像這樣:
APlugin.CreateForm(''''TCustomerForm'''');plugin 物件的 CreateForm 方法就會到串列中搜尋註冊過的類別,取得對應的類別參考並建立其實體(是不是有點像 COM 所做的事情?)。
嗯,我想這樣的提示應該夠了,最重要的還是要自己實際去撰寫及除錯程式碼以獲得更深刻的體會,真能如此,這個 Design Pattern 就會完全融入你的知識體系裡面,以後不加思索便可以運用自如了。
結語
在這份文件裡面主要是介紹以 Delphi 來設計 plugin 模組的實作過程,其中運用了介面程式設計的技巧(包括介面的參考計數以及物件生命週期的控制)以及 Design Patterns 來解決設計時遭遇的問題,這也是學習的重點之一。
在一個多人開發的專案裡,如果您的責任是設計主程式框架,當您要以 DLL 來切割應用程式時會怎麼做呢?這篇文章裡面展示了一種可能的設計方式,如果您有不同的想法或者對本文有任何建議,都很歡迎您來信指教。
Delphi 的 DLL 記憶體漏洞
最後,雖然不是本文的主題,但也頗值得注意的,就是動態載入的 DLL 在釋放時會有 4K 的記憶體漏洞,而且 Delphi 5 和 6 都有這個問題,你可以閱讀下面兩份文件,其中有詳細的說明並提供解決之道:
- Memory Lost And Found...And Release by Roy Nelson.
http://www.thedelphimagazine.com/samples/1328/1328.htm - VCL leak fix for dynamic DLLs by Dejan Maksimovic.
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=16380
註1.
由於 DLL 版本的更新可能使得原本叫用它的程式無法正常運作,因此以不同的檔名區分版本(例如:MFCxx.DLL),使得硬碟裡面必須保存同一種 DLL 的多個版本,即使使用者將應用程式移除了,卻不敢放心的移除相關的 DLL 檔案,以免其他應用程式因為缺少了這個檔案而無法運作,這種情況所形成的問題稱為 DLL hell。COM 的出現有解決此問題的企圖(透過執行時期詢問元件支援的介面),但似乎並不理想,直到 .NET 的問世而終於有了比較好的解決方案。 註2. 可以到 http://www.geocities.com/huanlin_tsai/ 的〔心得分享〕區找到相關文章。不可諱言,以上所說的難免摻雜了個人的因素,也許其他人在使用 package 時並未發生上述問題,而且使用 package 的方式也有許多優點,在此僅將個人實際應用時的狀況與感覺描述出來,若有謬誤之處尚請各方不吝指正。 註3. Singleton 樣式:提供單一窗口來建立類別的實體,以確保只有一個類別的實體存在。參考 [GHJV95] 的書。
參考資料
- Delphi 學習筆記。作者:錢達智。碁峰資訊,1998。
- [Cantu2001] Marco Cantu. Mastering Delphi 6. SYBEX, 2001.
- [Harmon2000] Eric Harmon. Delphi COM Programming. MTP, 2000.
- [GHJV95] E. Gamma, R. Helm, R. Johnson, J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995. 中文版:物件導向設計模式,葉秉哲。培生,2001。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash
