使用BPL加载Delphi对象运行时

时间:2009-11-09 11:01:54

标签: delphi dll package bpl

我在一个单元中有一个班级。通常,当我更改其方法的算法时,我必须重新编译它并作为一个整体提供补丁。 我想用DLL创建类的实例。在delphi.about.com中搜索后,我发现不使用DLL,而是使用BPL。它是Delphi的DLL。问题几乎是我发现的所有例子都只是告诉我们如何导出一个函数。 我想动态加载BPL,每当我替换BPL时,我都可以获得该类的最新算法,而不仅仅是我导出的函数。

第一条我读过:
- http://delphi.about.com/od/objectpascalide/a/bpl_vs_dll.htm
- Plugins system for Delphi application - bpl vs dll?
- http://delphi.about.com/library/weekly/aa012301a.htm

非常感谢任何URL或SAMPLE如何从头开始创建BPL以封装组件或类。


亲爱的大师,

假设我有这样的代码:

unit unitA;

interface

type
  B = class(TObject)
  public
    procedure HelloB;
  end;

  A = class(TObject)
  public
    function GetB: B;
    function HelloA: String;
    procedure Help;
  end;

  implementation

  uses
      Dialogs;

  { B }

   procedure B.HelloB;
   begin
     ShowMessage('B');
   end;

  { A }

  function A.GetB: B;
  begin
    Result := B.Create;
  end;

  function A.HelloA: String;
  begin
    Result := 'Hello, this is A';
  end;

  procedure A.Help;
  begin
    //do something
  end;

  end.

我想导出A的所有公共方法。如何使其成为DLL? 如何从其他单位使用它来导入它? 让我们说:

 var a: A;

 a := A.Create;
 a.GetB;
 showMessage(a.HelloA);

A未在单元中声明(它在DLL中)。 请指教。


乌拉。我昨晚得到了它。我所要做的就是使对象实现一个接口,该接口在调用者单元中用于捕获DLL返回的对象实例。

谢谢大家。

6 个答案:

答案 0 :(得分:4)

梅森已经把它钉了出来,但让我详细说明为什么BPL不是你想要的。 BPL是Delphi IDE加载共享相同内存管理器和RTL的组件的一种手段。 (类型标识几乎透明地使用BPL)

但是,您所依赖的依赖关系几乎总是不可接受的。除了IDE之外,无论如何都无法处理不同版本的RTL和VCL。

当您仅传递应用程序及其DLL之间的接口引用时,您根本不必共享RTL,VCL或共享包。

这也意味着你可以用另一种语言编写一些DLL(C ++,C#,FPC,另一种Delphi版本),并且仍然使用对象。当您不想移植主应用程序但仍想使用Delphi或Delphi版本不可用的现有库时,这可能很诱人。

答案 1 :(得分:2)

将类放在外部文件中的问题是您的主应用程序需要知道某种方式来引用它。它要么必须从作为虚方法公开所需的所有方法的基类继承,要么实现包含所需的所有功能的接口。

如果您已经知道对象的界面应该是什么样的,并且您正在改变的是实现细节,例如内部算法,可能最简单的方法是让您的类实现一个接口并将其放在DLL中导出一个返回此接口实例的函数。这样您就不必担心将应用程序分解为打包,这可能会非常麻烦。

答案 2 :(得分:2)

我在您的问题描述中没有看到任何内容,表明您需要从包中显式导出任何内容,或者您​​需要在运行时动态加载它。相反,您的函数驻留在可以与主程序分开替换的运行时包中就足够了。

启动一个新的软件包项目,并将您的类的单元与其依赖的任何其他单元一起移动到该项目中。编译项目。如果编译器警告“隐式包含”任何其他单元,也将它们添加到包中。

现在,从EXE项目中删除任何包单元。不应该有任何单位都是这两个项目的成员。接下来,在EXE的项目选项中打开“使用运行时包构建”复选框。将包添加到以分号分隔的包名列表中。 RTL和VCL包也可能在该列表中。

编译这两个项目,你就完成了。

如果您对类实现进行了更改,则只能重新编译该包并向客户发送新版本。使用新文件替换原始文件时,程序将自动获取新更改。该程序包列在程序的导入表中,因此操作系统将在加载EXE时自动加载BPL文件。 EXE不需要运行任何特殊代码来加载包。

答案 3 :(得分:0)

Delphi可以创建DLL来导出函数或BPL导出组件。

您可以创建组件,编译它(使用与主应用程序相同的编译器设置),Delphi将创建.bpl。然后将此组件导入Delphi并使用此compomponent作为包编译您的应用程序。

我使用Delphi 4创建的组件的经验证明,一个大型应用程序比具有单独.bpls的应用程序更可靠。它是多线程服务器,如果单独编译它可以正常工作,如果使用软件包编译,则在短时间内崩溃。我希望Delphi的新版本在这方面有所改进。

请注意内存管理(在app中不要释放包中分配的内存,反之亦然)和编译器设置。

如果您喜欢about.com,那么此链接将非常有用:Introduction to Packages; BPLs are special DLLs!

答案 4 :(得分:0)

BPL有它们的用法。例如,如果你必须像Erp一样制作一个非常庞大的应用程序,你需要认真地尝试使用BPL。

另一方面,BPL不对崩溃的应用程序负责。 BPL的使用不当就是这样。

答案 5 :(得分:-1)

您可以尝试使用MAF组件,它们可以为您处理插件等,而无需额外的代码。附带教程和带源代码的演示应用程序。

http://www.maf-components.com