访问Delphi BPL中的公共方法和属性

5

我有一个加载了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”?

2
展示一下你的代码长什么样子。加载BPL文件有多种方法,答案取决于你是如何进行操作的。 - David Heffernan
请参考以下 Stack Overflow 问题:execute-a-method-from-a-form-created-by-class-reference-delphi - LU RD
你写了这个BPL吗?为什么不导出一个名为GetMainForm的函数,然后调用function GetMainForm:TForm,然后就可以访问它了呢?你不能使用常识方法吗?一旦你知道了类并且可以枚举它们,甚至可以创建它们的实例,你打算做什么?在你的主应用程序中,为什么不指定适合你问题域的IPluginInterface,而是直接转到底层类类型呢? - Warren P
1
你的可执行文件对bpl中的'TForm1'一无所知,只知道它是一个TForm(或者从TForm派生而来)。因此,你只能访问TForm的方法和属性。不管你喜不喜欢,François的回答是正确的答案。 - Sertac Akyuz
2个回答

10
在动态加载的bpl中使用TOptionalForm的一个优点(从“optional”这一位可以推断出)是避免应用程序特定持有TOptionalForm类的定义(它在包含该单元的包中而且只有那里才有)。
这意味着除非您使用以下方法之一,否则您的应用程序无法了解有关它的任何信息: - 共享基类 - 声明要访问的属性和方法的接口 - 使用一些基本的RTTI来访问已发布的属性和方法。 - 使用一些扩展的RTTI来访问公共属性和方法(如果您使用的是D2010或更高版本)。 - 调用来自bpl的一些外部例程,这些例程接受基类参数(或TObject/指针类型),并将其在内部强制转换为TOptionalForm。
这是非常笼统和一般化的,需要更多关于您的代码的精确信息才能进行细化...

2
如果需要动态加载BPL,应该使用-如François所提到的:
  • 一个抽象类(更像Delphi)
  • 一个接口(我认为更干净,经验更好)
将其放置在仅限接口的单元中,由主应用程序和表单BPL同时使用。
我使用一个中间的“合同/接口”BPL,由主应用程序和动态加载的BPL静态使用。
在使用接口的情况下,还可以查看$WEAKPACKAGEUNIT指令,以进一步解耦BPL和应用程序。
评论中提到-通过使用DLL导出或RTTI,您基本上会绕过BPL的整个重点,即类型和命名空间共享。

1
我给你一个简单的例子,如果你能完成它,我会给你奖励。 - DRokie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接