我做了一些关于模块化应用程序机制的测试。
我尝试的基本方法是在运行时加载包,并在其中玩类。
我的测试围绕着在我的包中构建表单,并从我的主机应用程序加载表单"TCustOrder">,测试非常成功。
问题是:
我的TCustOrder具有名为"Client:TObject"的属性,我如何从主机应用程序访问此属性
代码:
var x : HRESULT ;
AClass : TPersistentClass ;
FormOrder : TForm ;
begin
x := LoadPackage('Cutorder.bpl') ;
if x <> 0 then
begin
AClass := GetClass('TCustOrder');
if AClass <> nil then
FormOrder := TComponentClass(AClass).Create(Application) as TForm;
if Assigned(FormOrder) then
begin
FormOrder.Show
end;
end;
应用程序应该知道使用它的类的基础。接口、协议、规范,你能想到的。特定的包给出了它的特定实现。
因此,基于BPL和传统对象的整体结构应该是您可以在VCL中观察到的结构。
Base.BPL-包含插件提供的实现的TBaseClass
和TList<TBaseClass>
。它还包含主程序使用它所需的所有虚拟方法和属性
class constructor TBaseClass.CreateClass;
begin
MyList := TList<TBaseClass>.Create;
end;
class destructor TBaseClass.DestroyClass;
begin
FreeAndNil(MyList);
end;
class procedure TBaseClass.RegisterClass;
Begin
MyList.Add(Self);
end;
class procedure TBaseClass.UnRegisterClass;
Begin
MyList.Remove(Self);
end;
App.Exe会将Base.BPL列在其运行时包中(在项目选项中),并使用Base.BPL作为插件的"汇合点"。
Plugin.BPL会将Base.BPL列为所需的运行时包,并将其用作集合位置。
TMyClass1 = class (TBaseClass);
...
initialization
TMyClass1.RegisterClass;
finalization
TMyClass1.UnRegisterClass;
end.
My TCustOrder具有名为"Client:TObject"的属性,如何从主机应用程序访问此属性
type (** Base.BPL **)
TBaseClass = class ...
protected function GetClient: TObject; virtual; abstract;
public property Client read GetClient;
...
end;
type (** Plugin.BPL **)
TMyClass1 = class(TBaseClass) ...
protected function GetClient: TObject; override;
...
end;
注意,至少DelphiXE2在卸载动态包时倾向于破坏字符串数组常量。如果它在2010年2月成立,那就不要了。在XE4中,它被修复了。所以"龙可能在这里"。在现代Delphi中,RTL/VCL中有很多错误,请准备好调试它们。