[英]Dynamically loaded BPL's sharing code / passing objects
我正在考慮使用動態加載BPL並將主應用程序中的對象實例傳遞給BPL中的方法。 這造成應用程序和BPL使用的問題單元。
我寫了一個小小的原型,它做了這個,並很好奇Delphi如何內部管理應用程序中定義的類與BPL之間的差異。
例如,說一個基本的Widget類,如:
TmyWidget = class
private
fId:Integer;
fDescription:String;
public
procedure DoSomething1();
end;
現在,應用程序和BPL是使用包含TmyWidget類的單元構建的。 之后,TMyWidget中的某些內容發生了變化,應用程序被重建,但是BPL不是(反之亦然。)我添加了另一個方法DoSomething2()並在應用程序中創建了一個TmyWidget實例並將其傳遞給BPL進行處理並在基本的例子,它的工作原理。 但它顯然充滿了潛在的問題。
如果另一個動態加載的BPL也使用TmyWidget,那么事情變得更加有趣。 它似乎工作,但它絕對不是理想的。
主要問題是 - 如何通常將對象傳遞給主應用程序和DLL或BPL? 我以前從來沒有嘗試過,而且可能有充分的理由,但我有這個想法適合這種方法......
我想最好的方法是序列化對象並將這些字節傳遞並在DLL / BPL中反序列化,此過程注意到主機和動態加載模塊之間可能存在的版本差異,但我希望新的SimpleSharedMem選項可能會帶來這個新功能而沒有序列化的開銷,但它似乎不是很有用,除非你嚴格保持app和dll重建任何共享代碼更改......但在這個原型中,應用程序將保持相當穩定並且動態加載的模塊將經常更改,並將功能添加到TmyWidget。 (服務器應用程序充當基於客戶端請求構建TmyWidget的工廠,應用程序將實例傳遞給各個模塊進行處理。)
...很奇怪Delphi如何在內部管理應用程序中定義的類與BPL之間的差異
Delphi通過不允許它來管理它。 你不能同時在多個包中有一個具有相同名稱的單元:如果你這樣做,你會收到一條錯誤消息,說明類似於Package XYZ already contains ABC
東西Package XYZ already contains ABC
(暫時還沒有看到......) 。 由於類型名稱包含單元名稱,因此在兩個不同的包中不能使用相同的類型。 除非它是由它的GUID定義的接口,否則這是一個不同的故事。
...通常如何將對象傳遞給主應用程序和DLL或BPL?
你沒有將對象傳遞給DLL,這不是一個好主意。 當您需要將對象傳遞給BPL時,請確保將該BPL的基類定義為第3個BPL。
例。 您的TmyWidget
多態行為可能是使用一些虛擬方法定義的。 確保你有一個定義所有這些虛擬方法的TmyWidgetBase
類,從該基類派生所有TmyWidget
並傳遞類型為TmyWidgetBase
對象。 確保TmyWidgetBase
類在它自己的Package中。
當我嘗試這樣做時,我最終得到了一個小的“bootstrap”exe和很多BPL的。 基本上所有邏輯都在BPL中,以便於傳遞對象。
我工作過的其中一個項目已經成功使用了大量的運行時包十多年了,所以我將分享一些處理包的經驗。
正如Cosmin指出的不同包裝不能包含相同的單位。 如果使用隱式鏈接,通過向另一個包的requires子句添加包,或者通過向Project Options中的Runtime包列表添加包,編譯器將為您完成工作並報告以下錯誤消息之一:
E2199: Packages '%s' and '%s' both contain unit '%s'
(如果您的編譯項目依賴於包含相同單元的兩個包)
E2200: Package '%s' already contains unit '%s'
(如果你編譯包含一個單元的包,它已包含在它所依賴的一個包中)
如果使用顯式鏈接,使用LoadPackage,通常會在運行時嘗試檢查(盡管可以繞過它)並引發:
EPackageError:無法加載包'%s'。 它包含單元'%s',它也包含在包'%s'中
解決這些錯誤並不是那么困難。
如果你有兩個需要使用單元的軟件包,只需讓其中一個包含單元而另一個需要第一個。
如果你有兩個需要使用彼此包含的單元的軟件包,你必須將這些單元移動到一個可以依賴的新軟件包。
隱式鏈接包具有以下優點:您可以直接訪問類定義,就像它們是靜態鏈接一樣。 只需將一個單元添加到您需要使用它的單元的uses子句中。編譯器和運行時環境負責解決所有問題。
顯式鏈接的包需要依賴初始化部分中的類注冊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.