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

发布于 2024-12-21 22:55:42 字数 1166 浏览 1 评论 0原文

我有一个应用程序加载 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”?

I have an application that loads a BPL that as inside a simple form.

This form is an optional option of the main application.

The BPL loads correctly, the form is shown correctly, but I don’t know how to access the public methods and properties of the form inside the bpl.

Can anyone provide a simple example?

my code:

// 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.

How can i access "PublicMthd" in Tform1 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

游魂 2024-12-28 22:55:42

在动态加载的 bpl 中使用 TOptionalForm 的好处之一(假设这是来自“可选”位))是为了避免您的应用程序专门保存 TOptionalForm 类的定义(它位于包中包含的单元中,并且仅在此处) )。

这意味着您的应用程序无法了解任何有关它的信息,除非您使用以下任一方法:
- 共享基类
- 声明您要访问的属性和方法的接口
- 一些基本的 RTTI 来访问已发布的属性和方法
- 一些扩展的 RTTI 来访问公共属性和方法(如果您有 D2010 或更高版本)
- bpl 中的一些外部例程接受基类参数(或 TObject/指针),在内部将其类型转换为 TOptionalForm。

这是非常模糊和笼统的,需要对您的代码进行更精确的改进......

One of the interest of having TOptionalForm in a dynamically loaded bpl (assuming this from the "optional" bit)) is to avoid for your application to hold the definition of the TOptionalForm class specifically (it's in the unit contained in the package and only there).

That means that your application cannot know anything about it unless you use either:
- a shared base Class
- an Interface declaring the properties and methods you want to access
- some basic RTTI to access published properties and methods
- some extended RTTI to access public properties and methods (if you have D2010 or later)
- some external routines from the bpl accepting a base class parameter (or TObject/pointer) typecasting it as TOptionalForm internally.

This is very vague and general and more precision about your code would be needed to refine...

魔法少女 2024-12-28 22:55:42

如果您需要动态加载 BPL,您应该使用 - 正如 François 已经提到的:

  • 一个抽象类(更像 Delphi 或)
  • 一个接口(我认为它更干净并且有更好的经验)

放置在仅接口中主应用程序和表单 BPL 使用的单位。

我使用中间“契约/接口”BPL,由主应用程序和动态加载的应用程序静态使用。

在接口使用的情况下,还可以查看 $WEAKPACKAGEUNIT 指令以进一步将 BPL 与应用程序解耦。

要评论评论 - 通过使用 DLL 导出或 RTTI,您基本上会绕过 BPL 的全部要点,即类型和命名空间共享。

If you need to load the BPL dynamically, you should use - as already metioned by François:

  • an abstract class (which is more Delphi-like or)
  • an interface (which I consider cleaner and have better experience with)

placed into an interface-only unit used by both the main application and the form BPL.

I use an intermediate "contract/interface" BPL, statically used by both the main application and the dynamically loaded ones.

In the case of interface usage, may also look at the $WEAKPACKAGEUNIT directive to further decouple the BPL fom the application.

To comment on the comments - by using DLL exports or RTTI, you would basically bypass the whole point of BPLs, which is type and namespace sharing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文