`
美丽的小岛
  • 浏览: 309331 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

BPL VS DLL

 
阅读更多

第一部分:有关包的介绍

一般我们编写编译一个DELPHI应用程序时,会产生一个EXE文件,也就是一个独立的WINDOWS应用程序。很重要的一点:区别于Visual BasicDELPHI产生的是预先包裹的应用程序是不需要大量的运行库(DLL's)。

假设:打开Delphi默认的工程(只有一个空白form),F9她将编译生成一个大约295 KB (Delphi 5)的可执行文件。然后打开Project | Options,把‘Build with runtime packages’选上再编译一下,EXE文件大小就只有15 KB左右了。
我们编译一个DELPHI应用程序时默认地没有选择'Build with runtime packages',编译器将把程序运行所需要的代码直接写入你的EXE文件中,因此产生的程序是一个相对独立的程序,并不需要任何附属的支持文件(例如动态运行库文件DLL),这也就知道了为什么DELPHI产生的应用程序为什么都那么大。

要建立尽可能小的DELPHI程序,方法之一就要充分发挥Borland package libraries的作用,简称BPL

先说什么是包

简而言之,一个包就是一个在DELPHIIDE环境中被DELPHI应用程序共享的特殊的动态链接库。包允许我们通过多级应用将我们的程序的一部分当做一个分离的模块供其他应用程序来共享。

包大致可分为运行期包(Run-time packages)和设计期包(Design-time packages):

运行期包-当运行程序时提供VCL和库函数的支持,操作上很类似标准的动态链接库。

设计期包-用来在DELPHIIDE环境安装控件和为控件建立特殊的属性编辑器。设计期包允许包含控件、属性和控件编辑器等等,在IDE环境中,这类包是程序设计所必需的,也仅仅是DELPHI使用,并不和开发的应用程序一起分发。

知道这些包的运用,我们也就知道了运行期包是如何做处理和它们对DELPHI程序员有什么帮助了。

有一点必须说明:想很好地运用包并不要求你先成为一个成熟的控件编写者。DELPHI编程初学者也可以和应该尝试去接触包的概念,这将有利于你更好地理解包和DELPHI的工作关系。

第二部分:适时运用包裹和DLL

一般都认为加入WINDOWS操作系统中的动态运行库是一种最有用最高效的应用。在WINDOWS系统中,很多应用程序同时运行可能会引起了内存方面的问题,很多程序执行相似的操作任务,但各自又由不同的代码来控制并完成任务,动态运行库的作用就是将你的执行程序中的这些代码放到一个系统共享环境下的DLL中去。可能最为直观的动态链接库例子就是WINDOWS操作系统自己和它本身所带的API了。

动态链接库通常都是用来集合过程(procedure)和函数(function)以供程序调用。当然我们在编写动态链接库的同时,也可以把一个DELPHI FORM放到一个DLL中去(例如一个AboutBox FORM),此外我们也可以在DLL中存储程序所需要的资源(resources)。更多关于DELPHI如何操作使用动态链接库,请参考相关书籍,不再赘述。

在比较DLLs BPLs之前,我们先要知道可执行文件的2种代码链接的方式:静态链接和动态链接。

静态链接就是当一个DELPHI工程被编译的时候,工程所需要的所有代码将被直接链接入你的程序执行文件。结果就是执行文件将包含程序所需要使用到的所有单元(units),你也许会说这样代码有点冗长,因为在通常默认情况下,一个FORM单元的uses子句列举了至少5个基本单元(如:Windows, Messages, SysUtils,...),尽管如此,DELPHI还是能够智能地自动链接单元中真正要用到的代码到工程代码中,从而尽可能地减少了执行文件的大小。使用静态链接,我们的应用程序就是一个相对独立的程序,不需要任何额外的支持文件或动态链接库(暂时不考虑BDEActiveX构件)。DELPHI中默认使用的就是静态链接方式。

动态链接就是应用程序将和标准的动态链接库(DLLs)一起运行。动态链接方式不需要将代码直接建立到每个应用程序中去,单独为多个应用程序提供多线程的库函数支持,任何程序运行期间才需用到的包才将被加载,更值得一提的是:程序在动态方式需要调用的包是自动加载的,因此你不需要专门写加载包的代码。

方法:简单地选中在Project | Options 对话框中'Build with runtime packages'复选框后,再次编译你的程序,你的程序代码将自动链接到动态运行包,而不是将引用单元都静态链接入你的工程执行文件。

是选择BPL 还是 DLL?区别又在哪里?

你可能很奇怪为什么要选择使用运行期包,而不是DLL,或者还有其他什么方法。

相对于DLL而言,包裹的概念是DELPHI开发中所特有的,就是说其他语言编写的应用程序不能引用DELPHI建立的包裹。即使包是一种被DELPHI编写的应用程序所使用的动态链接库,它也同时提供给了DELPHI程序员更多的库函数支持。

通常我们在DELPHI中建立动态链接库(DLLs)是用来存储不同环境下应用程序所需要使用到的过程和函数,而包不仅能够包含代码单元(untits)、构件和FORMs,还能包含DELPHI中的类(classes-这就使我们能够在其中引用对象向导编码(object oriented code)。在包裹中,我们可以保存完整的通用DELPHI构件,而动态运行库(DLL's)对此则无能为力了。

此外,在缩减程序代码上,DLLsBPLs扮演着同样重要的角色,其主要原因就是在使用包裹或动态链接库技术后,都直接地减少了程序的文件大小。当然,还要说明的是:执行程序需要加载的DLLsBPLs也可能会是很庞大的。例如如果需要分发你的包裹文件(主要是VCL包,vcl50.BPL)至少有2MB左右。

尽管如此,如果你是要分发共享同个包的多个应用程序,你就可以省很多事了。当用户方系统中已经存在程序运行需要的部分文件(如:标准的DELPHI BPLs)后,就只需要下载程序的最小执行文件了。如果你的程序工程主要是通过INTERNET等方式分发和开展,那效率显然有很大的提高。

同时,包的应用也节省系统内存,因为动态链接的结果就是:只有一个VCL被读入内存供所有使用运行期包的DLEPHI应用程序使用。

包裹的版本问题

当你想升级你的动态链接库时(改变其中一些执行函数),你可以简单地编译产生新的程序文件,并上载新版本文件,所有正在使用该动态链接库的应用程序仍将工作(除非你已经将存在的旧版本程序去除)。

换个角度来讲,在升级新包裹文件的同时,不要忘记升级程序的执行文件。正如你所了解的,包裹文件就是一个单元文件(units)的集合,所有编译过的单元文件(DCU)都含有版本信息,因此,除非我们有单元文件的源码(source),否则我们不能在DELPHI45中使用编译过的单元,所以一旦我们改变了单元文件中接口部分uses子句中列举出的任一单元文件,该文件就需要重新编译。编译器将检查DCU文件的版本信息,并决定单元是否需要重新编译。因此我们不能在DELPHI5编译的应用程序中使用在DELPHI6下编译的包,任何为你的应用程序服务的包和你的应用程序必须在相同环境下编译。

因此,当给包裹命名的时要保留包裹名中包含有DELPHI的版本信息(如'AboutDP50',其中50就代表Delphi 5)。这可以有效防止文件版本的冲突问题,也可以避免很多不必要的麻烦,包使用者可以更清楚包的版本和包裹适用于哪个DELPHI编译器。

如果你要分发运行期或设计期包给其他DELPHI程序员,建议同时提供了.DCP(含有包的头信息和各个单元文件)和.BPL文件,还有包中所包含的所有单元文件的.DCU文件。

第三部分:建立和使用运行期包
建立一个包裹
建立一个包很简单,但在建包之前要做一些准备工作。首先,你需要知道你准备建立哪种类型的包文件:运行期包还是设计期包,或两者都是;其次是,建立、调试,反复地测试你想放置到包中去的单元文件;最后,为建立的包裹文件命名,还有就是选择一个合适的地方来存放文件。

建立一个新的运行期包,按照以下步骤:

1.启动DELPHI,并选择File | Close All关闭默认的工程。

2.选择File | New...,在"New items"对话框中的"new"页面中双击Package图标(如图),就会出现包裹编辑器(如图):包裹编辑器包含2个文件夹:ContainsRequires

3.点击Add按钮,可以增加一个单元文件(构件或是一个简单的代码单元文件)。

注意:你添加的是PAS源码文件而不是编译后的DCU文件。当你添加单元文件的同时,包中的单元的名字就显示在包裹编辑器的Contains文件夹中了。如图中添加了FindFilePictureClip的单元文件。

4.打开Requires文件夹,展开的列表表示包裹所需要的包的DCP文件,包裹文件最基本的就需要引用含有绝大部分标准可视控件的vcl50.dcp文件。

5.当你添加完单元文件,单击Options按钮,在Description面板中的Usage options组中你需要选择包裹种类:是设计期包,还是运行期包,或者两者都是。如果选择Runtime only(仅运行期包),其他包的使用者将无法将图示2个构件安装到IDE环境中去。

6.使用File | Save保存包工程文件(DPK),然后保存包文件,如AboutDP50,包裹文件的命名将很重要。

7.在包裹器中,单击Compile按钮来编译包。

8.如果不出什么意外,编译包后将建立一个包裹文件(BPL文件),期间你可能还要确定你必须增加的其他包裹(例如VCLX50),这些包都将在Requires文件夹中列出。

9.完成,Borland package library文件已经成功建立,就等着使用了。

在包裹编辑器中有一个Install按钮,就是用来将当前包裹安装成一个设计期包的。如果包裹是run-time only(仅运行期包),那Install按钮将无法使用。

关于所建立的这些文件

除了DPK文件和那些单元源码文件,DELPHI还使用包裹的动态链接版本产生一个BPL文件和一个含有包内标识信息DCP文件,DCP文件就是包中所包含单元文件的编译文件(DCU)的标识信息的集合。

使用运行期包设计程序

开始使用动态链接编写应用程序时,不需要写代码去加载运行期包裹,只需要在Project | Options中做相关设置,选择在Packages页的Runtime Packages编辑框中的包裹列表,编译程序时将自动链接。应用程序要使用到一个运行期包时,使用ADD按钮来增加包裹文件。 

注意:尽管一个应用程序被链接到运行期包,程序的USES子句所列出的单元文件也必须都是存在的,编译运行期包裹只是告诉应用程序哪里可以找到构件代码而已。

当配置一个使用到运行期包裹的应用程序时,确定用户拥有可执行文件和程序所需的库文件(.BPL.DLL)。如果库文件在和EXE文件不同的目录下,必须将其指定到系统所能到达的目录。因此,最好的选择就是Windows\System系统目录。

总而言之

 

包裹使你能够有弹性地选择应用程序的分发方式,也使构件的安装变简单了,此外,使用包裹也减少了应用程序的文件大小,因此,使用包裹的开发方式还是具有不小的意义的。

分享到:
评论

相关推荐

    delphi exe+bpl+Dll框架(源代码和示例)

    在Delphi中,除了可以创建独立的EXE应用程序之外,还可以利用BPL(Binary Package Library)和DLL(Dynamic Link Library)来构建更加灵活和可扩展的软件框架。本资源"delphi exe+bpl+Dll框架(源代码和示例)"提供...

    delphi bpl和dll调用框架

    BPL(Binary Package Library)和DLL(Dynamic Link Library)是Delphi中两种重要的模块化扩展机制,它们允许开发者将代码拆分为可重用的组件。"delphi bpl和dll调用框架"是一个专门针对这两个概念设计的实践框架,...

    XE2调用BPL和DLL方法

    在Delphi编程环境中,XE2版本提供了一种强大的机制,允许开发者将大型或复杂的项目分解为多个可重用的组件,这些组件可以是BPL(动态链接库)或DLL(动态链接库)。这种方式有助于提高代码的组织性,降低模块间的...

    BPL和DLL中Form共享数据库连接和模块调用的例子.rar

    在Delphi编程环境中,BPL(Borland Package Library)和DLL(Dynamic Link Library)是两种常见的库文件格式,用于代码重用和模块化开发。本案例“BPL和DLL中Form共享数据库连接和模块调用的例子”展示了如何在这些...

    BPL与DLL共享Form通讯的例子

    在Delphi编程环境中,BPL(Borland Package Library)和DLL(Dynamic Link Library)都是用于代码重用和模块化开发的重要工具。本示例主要探讨如何在BPL和DLL之间实现Form的共享以及数据库连接的共享,以便进行模块...

    EXE.BPL.DLL.Interface.项目解决方案演示.rar

    标题中的"EXE.BPL.DLL.Interface.项目解决方案演示.rar"揭示了这是一个关于Delphi编程的项目,重点在于如何在EXE(可执行文件)、BPL(Delphi库包)和DLL(动态链接库)之间建立接口。项目解决方案通常是指为解决...

    Delphi EXE BPL DLL Interface Package 解决方案

    Delphi EXE BPL DLL Interface Package 解决方案 Delphi EXE BPL DLL Interface Package 解决方案 Delphi EXE BPL DLL Interface Package 解决方案

    Delphi中的包 关于bpl, dll, exe的编译、连接和执行

    详述了Delphi中各种库的用法和区别:BPL DLL EXE的联系与区别

    XE2调用BPL和DLL中的FORM窗体源码演示

    当程序模块较多时,不能只编译成一个EXE文件,这是就需要把不同模块分别编译在不同的BPL或者DLL文件中。 本例子演示XE2下调用BPL和DLL文件中FORM的方法。 演示DLL或BPL共享主控窗口连接、接口的方式。

    Delphi EXE + BPL + DLL框架(源代码和示例)

    Delphi EXE + BPL + DLL框架(源代码和示例) 在Delphi开发领域,追求灵活与高效的你是否还在为频繁的EXE更新而头疼?来尝试这一革命性的框架设计吧!本资源为你呈现一个先进的Delphi应用程序架构,它将彻底改变你对...

    DelphiDLL.rar_BPL_delphi bpl d_delphi dll_delphi exe dll_exe dll

    标题中的“DelphiDLL.rar_BPL_delphi bpl d_delphi dll_delphi exe dll_exe dll”暗示了这个项目包含了以下知识点: 1. **BPL的创建与使用**:如何在Delphi中创建BPL包,以及如何在项目中导入和使用这些包。 2. **...

    delphi 调用dll 和 bpl的例子

    在Delphi编程环境中,DLL(动态链接库)和BPL(包)是两种常见的代码复用方式。DLLs允许开发者将功能封装到单独的模块中,以便多个应用程序可以共享同一段代码,而BPLs则主要用于组件的组织和分发。下面我们将详细...

    vcl60.bpl rtl60.bpl CC3260MT.DLL BORLNDMM.DLL

    1. **vcl60.bpl**:这是Visual Component Library(VCL)的一个版本库文件,对应于Delphi 6。VCL是 Borland 公司(现为Embarcadero Technologies)开发的一种用户界面库,用于构建Windows应用程序。它提供了大量的...

    DBX 三层 DEMO EXE+BPL+DLL

    在“DBX 三层 DEMO EXE+BPL+DLL”这个压缩包中,我们可以看到一个演示了如何使用DBX实现三层架构的示例程序。三层架构是一种常见的软件设计模式,它将应用分为三个主要部分:表示层(Presentation Layer)、业务逻辑...

    rtl60.bpl BORLNDMM.DLL CC3260MT.DLL vcl60.bpl

    总结来说,rtl60.bpl、BORLNDMM.DLL、CC3260MT.DLL和vcl60.bpl是Delphi编程环境的关键组成部分,对于理解和开发Delphi应用至关重要。它们共同构成了Delphi的强大功能,使得开发者能够快速、高效地创建Windows应用...

    计算机软件-编程源码-EXE.BPL.DLL.Interface.项目解决方案演示.zip

    在计算机软件开发中,"EXE.BPL.DLL.Interface.项目解决方案演示.zip"这个压缩包文件涉及到了几个关键概念,包括可执行文件(EXE)、动态链接库(DLL)、包文件(BPL)以及接口(Interface)。这些是编程中非常重要的...

    分享一款dll文件修复工具

    DLL(Dynamic Link Library)是Windows操作系统中的一个重要组成部分,它是一种共享库,包含了各种函数和资源,可供多个程序同时调用,以节省内存并提高效率。然而,由于各种原因,如软件冲突、病毒感染或误操作,...

    DELPHI BPL应用

    DELPHI BPL(Borland Package Library)应用是一种在Delphi编程环境中使用动态链接库(DLL)的方式,它允许开发者将代码组织成可独立编译的组件包,便于代码重用、模块化开发和系统扩展。在这个"DELPHI BPL应用"的...

    delphi开发的dll +exe +bpl 实例

    在Delphi中,我们可以创建三种不同类型的可执行模块:DLL(动态链接库)、EXE(可执行程序)和BPL(Delphi包)。下面将详细解释这些概念以及它们在Delphi开发中的作用。 1. DLL(动态链接库): DLL是Windows操作...

    BPL_调用举例(Delphi)

    - 出于性能考虑,尽可能减少BPL与DLL之间的交互次数。 #### 三、总结 本文通过具体的示例详细介绍了Delphi中BPL文件的基本使用方法,包括类的注册与反注册、BPL文件的安装与动态加载以及BPL与DLL的交互等几个方面...

Global site tag (gtag.js) - Google Analytics