我有一个应用程序,它在一个简单的表单中加载一个BPL。
此表单是主应用程序的可选选项。
BPL正确加载,表单显示正确,但我不知道如何访问bpl中表单的公共方法和属性。
任何人都可以提供一个简单的例子吗?
我的代码:
// Load the BPL on aplication Load
LoadPackage( 'About.bpl' );
// CAll for TForm1 inside the About.BPL
var
AClass: TClass;
AForm: TForm;
begin
AClass := GetClass('TForm1');
if AClass <> nil then
begin
Application.CreateForm(TComponentClass(AClass), AForm);
AForm.Show;
end;
// The unit TForm1 inside the BPL package
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
PublicMthd;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Procedure TForm1.PublicMthd;
Begin
ShowMessage('Inside call');
End;
initialization
RegisterClass(TForm1);
finalization
UnRegisterClass(TForm1);
end.
如何在Tform1中访问“PublicMthd”?
答案 0 :(得分:9)
在动态加载的bpl中使用TOptionalForm的一个兴趣(假设这来自“可选”位))是为了避免应用程序专门保存TOptionalForm类的定义(它在包中包含的单元中)只有那里。
这意味着除非您使用以下任一项,否则您的应用程序无法了解相关信息:
- 共享基础班
- 声明要访问的属性和方法的接口
- 一些基本的RTTI来访问已发布的属性和方法
- 一些扩展的RTTI来访问公共属性和方法(如果你有D2010或更高版本)
- 来自bpl的一些外部例程接受基类参数(或TObject / pointer),在内部将其类型化为TOptionalForm。
这是非常模糊和一般的,需要更精确的代码来改进...
答案 1 :(得分:2)
如果你需要动态加载BPL,你应该使用 - 正如François已经提到的那样:
放入主应用程序和表单BPL使用的仅接口单元中。
我使用一个中间的“契约/接口”BPL,由主应用程序和动态加载的应用程序静态使用。
在接口使用的情况下,也可以查看$WEAKPACKAGEUNIT
指令以进一步解耦应用程序的BPL。
要评论评论 - 通过使用DLL导出或RTTI,您基本上会绕过BPL的全部内容,即类型和命名空间共享。