使用 BPL 加载 Delphi 对象运行时

发布于 2024-08-10 18:15:31 字数 1581 浏览 3 评论 0原文

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

我读过的文章:
- http://delphi.about.com/od/objectpascalide/a/bpl_vs_dll .htm
- Delphi 应用程序的插件系统 - bpl 与 dll?< br> - http://delphi.about.com/library/weekly/aa012301a.htm

非常感谢任何 URL 或如何从头开始创建 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 返回的对象实例。

谢谢大家。

I have a class in a unit. Usually, when I changed the algorithm of its methods, I have to recompile it and deliver the patch as a whole.
I think to create the instance of the class using DLL. After searching in delphi.about.com, I found that instead of using DLL, I can use BPL. It is a DLL for Delphi. The problem is almost all examples I found is only telling how to export a function.
I want to dynamically load the BPL, and whenever I replace the BPL, I can get the latest algorithm of the class, not only the functions I export.

Article I have read:
- 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

Any URL or SAMPLE how to create a BPL from scratch to encapsulate a component or a class is greatly appreciated.


Dear Guru,

Suppose I have code like this:

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.

I want to export all public methods of A. How to make it a DLL?
How to use it from another unit where to import it?
let's say:

 var a: A;

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

A is not declared in the unit (it is in the DLL).
Please advise.


Hurray. I got it last night. All I have to do is make the object implement an interface which is used in the caller unit to catch the instance of object returned by the DLL.

Thank you all.

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

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

发布评论

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

评论(6

舂唻埖巳落 2024-08-17 18:15:32

Mason 已经解决了这个问题,但让我详细说明一下为什么 BPL 不是您想要的。
BPL 是 Delphi IDE 加载共享相同内存管理器和 RTL 的组件的一种方法。 (类型标识使用 BPL 几乎透明地工作)

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

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

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

Mason nailed it already, but let me elaborate on why BPLs aren't what you are looking for.
BPLs are a means for the Delphi IDE to load components that share the same memory manager and RTL. (Type identity works almost transparently using BPLs)

However, the dependencies you are getting tied up in are almost always unacceptable. Except for the IDE, which cannot handle different versions of RTL and VCL anyway.

When you pass only interface references between your application and its DLLs, then you don't have to share RTL, VCL or shared packages at all.

It also means that you could write some DLLs in another language (C++, C#, FPC, another Delphi version), and still use objects. Which can be tempting when you don't want to port your main app but still want to use existing libraries that are not available for Delphi, or your version of Delphi.

(り薆情海 2024-08-17 18:15:32

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

如果您已经知道对象的接口应该是什么样子,并且您要更改的只是实现细节(例如内部算法),那么最简单的事情可能是让您的类实现一个接口并将其放入一个导出返回此接口的实例的函数。这样您就不必担心将应用程序分解成包,这可能是一个真正的麻烦。

The problem with putting a class in an external file is that your main application needs to know some way to refer to it. It will either have to descend from a base class that exposes all the methods you need as virtual methods, or implement an interface that contains all the functionality you need from it.

If you already know what the interface of the object should look like, and all you're changing is implementation details such as internal algorithms, probably the easiest thing would be to make your class implement an interface and put it in a DLL that exports a function that returns an instance of this interface. That way you don't need to worry about breaking your app up into packages, which can be a real hassle.

梦过后 2024-08-17 18:15:32

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

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

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

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

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

I see nothing in your problem description suggesting you would need to explicitly export anything from the package or that you would need to load it dynamically at run time. Instead, it's enough that your functions reside in a run-time package that can be replaced separately from the main program.

Start a new package project and move your class's unit into that project along with any other units it depends on. Compile the project. If the compiler warns about "implicitly including" any other units, add those to the package, too.

Now, remove any of the package units from the EXE project. There should be no units that are members of both projects. Next, turn on the "build with run-time packages" checkbox in your EXE's project options. Add your package to the semicolon-separated list of package names. The RTL and VCL packages will probably also be on that list.

Compile both projects, and you're done.

If you make changes to your class implementation, you can recompile the package only and send a new version to customers. The program will automatically get the new changes when you replace the original file with the new one. The package is listed in the program's import table, so the OS will automatically load the BPL file when it loads the EXE. The EXE doesn't need to run any special code to load the package.

饭团 2024-08-17 18:15:32

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

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

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

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

如果您喜欢 about.com,那么此链接将会很有用:软件包简介; BPL 是特殊的 DLL!

Delphi can create DLL to export functions or BPL to export component.

You can create component, compile it (use the same compiler settings as in your main app), and Delphi will create .bpl. Then import this component to Delphi and compile your app with this compomponent as a package.

My experience with components created with Delphi 4 proved that one, big application is more reliable than application with separate .bpls. It was multithreaded server and it worked fine if compiled standalone, while crashed after short time if compiled with packages. I hope newer versions of Delphi improved in this area.

Be aware of memory management (in app do not free memeory allocated in package and vice versa) and compiler settings.

If you like about.com then this link will be useful: Introduction to Packages; BPLs are special DLLs!

心碎的声音 2024-08-17 18:15:32

BPL 有其用途。例如,如果您必须制作像 Erp 这样的非常庞大的应用程序,则需要认真尝试使用 BPL。

另一方面,BPL 不负责应用程序崩溃。 BPL 的错误使用会造成这种情况。

BPLs have their usage. For example if you have to make a very huge application like an Erp, you need to try to use BPLs seriously.

In the other hand, BPLs aren't responsible of crashing applications. Bad usage of BPLs does it.

迟月 2024-08-17 18:15:32

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

http://www.maf-components.com

you can try the MAF Components, they handle plugins and much more for you without extra code. Comes with tutorials and a demo application with source.

http://www.maf-components.com

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