标签: bpl

Delphi应用程序的插件系统 - bpl vs dll?

我正在编写应该具有加载插件功能的delphi应用程序.我正在使用JvPluginManager作为插件系统/管理器;)现在,在新的插件向导中,他们说最好使用.bpl类型的插件而不是.dll插件...这个解决方案与dll类型插件有什么优点?到目前为止,我发现只有这个解决方案的缺点:

  1. 我必须将所有通用接口单元放在单独的包中,以便在加载插件时不会抛出包含公共单元的其他包的任何错误

  2. 如果,让我们说,其中一个插件开发人员决定使用一些众所周知的单元(如synapse),默认情况下没有运行时包,第二个插件开发人员也会这样做,而不是碰撞 ...它在这里崩溃了. ..

那么,使用bpls而不是使用运行时包编译的dll实际上是什么呢?

提前致谢

delphi dll plugins bpl

23
推荐指数
2
解决办法
1万
查看次数

包(BPL)自动命名后缀

我为Delphi编写了很多组件和库,其中大部分都需要使用BPL Packaging才能将它们安装到IDE中.

这很简单并且运行良好,直到你想要维护一组Package Project Files(在一个Project Group中),但是也想为不同的Delphi版本编译和分发那些相同的包.

到目前为止,我一直在为每个版本的Delphi创建一个不同的Package Project,并明确地将Delphi版本标识符定义为后缀(例如Kinect_XE.bplKinect_XE2.bpl).

我知道,在包项目的项目选项中,在描述下,有字段LIB前缀和(更重要的是我的需要)LIB后缀.

我进一步意识到,如果我在LIB后缀中放置一个值,它将被附加到已编译的BPL文件名的末尾.

然而,我的问题是,首先是否可以让IDE自动使用IDE/RTL版本号填充LIB后缀字段,如果是,那么......怎么样?

我相当肯定这是可能的,因为看起来vcl120.bpl(及其各自版本的Delphi的对应物)可以仅使用vcl引用(作为要求)您自己的包,而不必键入完整的vcl120.事实上,这是我希望实现的相同行为......我的包可以在内部引用彼此(作为必要),而不必提供特定于版本的引用来容纳后缀.

同样重要的是,解决这个问题将使我能够在一个项目组中维护一组项目文件(除了XE2之外,由于平台的添加,其项目文件与以前版本的Delphi不一定表现得很好).

我怀疑我可能需要在LIB后缀字段中输入类似$(VER)(或类似的东西)的值,但这似乎不起作用,我已经搜索谷歌寻找正确的解决方案.

希望你能帮忙!

更新1

我现在正在编写一个IDE插件,用于(至少)Delphi 2007到XE2,它为DLL和BPL项目提供了一个名为AutoSuffix的新选项.当切换为On时,任何安装了AutoSuffix插件的IDE 都会立即将正确的IDE版本后缀应用于项目.

AutoSuffix插件将在未来24小时内提供(免费)适合所有人,这个问题相应地更新.

更新2

好的...... Delphi 2007很痛苦!到目前为止,我已经将AutoSuffix与2009年的XE2合作,但2007年需要更多时间(耐心赞赏).

更新3

似乎Embarcadero听到了我们对版本之间简化包装统一的集体呼声.

Mark将推动这一过程,看看未来版本的Delphi是否可以容纳{$ LIBSUFFIX AUTO}功能.我希望很快能收到回复是否会出现这种情况.如果是这样,它肯定会影响AutoSuffix在XE2和旧版本上的工作方式(目前它不提供简单的AUTO开关......它有自己的方法).

我现在希望EMB能够认真对待这个请求,将其作为一个不可或缺的特征提供给它,这样就可以在现有版本上使用AutoSuffix来统一所有版本的流程!

delphi bpl package

16
推荐指数
1
解决办法
2427
查看次数

调试时Delphi App有"无调试信息"

我们构建了一个使用包和组件的应用程序.当我们调试应用程序时,IDE中的"事件日志"通常会显示我们的BPL正在加载而没有调试信息("无调试信息").这没有意义,因为我们所有的包和EXE都是使用debug构建的.

_(each project) | Options | Compiling_
[ x ] Assertions
[ x ] Debug information
[ x ] Local symbols
Symbol reference info = "Reference info"
[   ] Use debug .dcus
[ x ] Use imported data references

_(each project) | Options | Linking_
[ x ] Debug information
Map file = Detailed
Run Code Online (Sandbox Code Playgroud)

我们有4个项目,都是使用运行时pacakges构建的:

  1. Core.bpl
  2. Components.bpl
  3. Plugin.bpl(同时使用#1和#2)
  4. MainApp.exe(使用#1)

观察到的问题

1)我们多次调试时,Components.bpl加载了调试信息,但"Local Variables"窗口中的所有值都是空白的.如果将鼠标悬停在代码中的变量上,则没有弹出窗口,"评估"窗口也不显示任何内容("结果"窗格始终为空白).

2)有时事件日志显示各种BPL的"无调试信息".例如,如果我们激活Plugin.bpl项目并设置它的Run | 将参数的主机应用程序作为MainApp.exe,然后按F9,除Plugin.bpl模块外,所有模块似乎都加载"Has Debug Info".加载时,事件日志显示"无调试信息".但是,如果我们关闭应用程序并立即按F9,它将再次运行它而不重新编译任何东西,这次Plugin.bpl加载了调试("有调试信息").

问题

1)什么会导致"局部变量"窗口显示值?

2)当BPL符合调试并且所有调试文件(dcu,map等)都可用时,为什么BPL有时会在没有调试信息的情况下加载?

delphi debugging packages bpl delphi-xe2

13
推荐指数
2
解决办法
8237
查看次数

Delphi插件框架

我想设计Delphi插件框架.有三个选项:
1.DLL
2. BPL
3. COM接口

每个选项都有一些缺点.

DLL - 带有MDI apllication的Promblem,来自插件的表单不能嵌入到主机exe-mdi应用程序中.
BPL - 必须使用相同版本的Delphi编译每个*.bpl插件和*.exe主机应用程序.
COM - 接口{xxx-xx-xxx-xx}必须在系统中注册,(regsvr)因此插件框架不能移植!

我上面写的一切都是真的吗?如果没有,请纠正我,还是有其他可能性?
谢谢

delphi com dll interface bpl

12
推荐指数
1
解决办法
3323
查看次数

解决BPL无法加载但仍已重新编译的Delphi BPL包问题(Windows VirtualStore文件系统问题)

我的一般问题是你如何排除故障"我的BPL不会因为依赖而无法加载,无论我清理和重新编译多少". 更新你可能认为你有一个干净的重新编译系统,但由于Windows的反奇迹及其文件系统虚拟化错误功能,你还没有.

当我尝试将我的设计时包(在本例中命名dclFsTee.bpl)加载到我的Delphi IDE中时(它是快速报告4 teechart包装器组件包),它抱怨:

The program can't start because tee7100.bpl is missing from your computer. Try reinstalling ...
Run Code Online (Sandbox Code Playgroud)

tee7100.bpl是不是在我的系统上的任何DCP或DCU文件,我知道引用.但显然,有些事情是错的,我找不到问题.

所有Delphi用户都面临着一百个"不会编译或不会加载"BPL问题.当被问及做什么时,通用副词是清理您的计算机.

但是,我现在花了几个小时来清理我的计算机,虽然一切都编译了文件,但显然必须有某些东西过时隐藏,因为我试图加载的结果BPL文件仍然想加载一个版本的几天前我从这个系统中删除的TeeChart BPL,以及我能找到的每一条痕迹.

我删除的Delphi 2007中的TeeChart内容包括$(BDS)\ Lib和$(BDS)\ Lib\debug文件夹中的所有内容,以及系统上的所有DCP和BPL文件夹.此外,每个名为TeeChart-unit的dcu文件都已消失.

一旦你走到了尽头,你接下来会尝试什么?(格式化硬盘,购买新电脑.)说真的.我认为我是一个聪明的人,但我有一个1 Tb的硬盘驱动器,一个运行到80多个文件夹的库路径,以及一个似乎组织良好的源代码存储库,但显然有些东西隐藏在我不能的地方找到它.

我有完整源代码的TeeChart Standard 2012,据我所知,我的开发机器不再包含delphi附带的"tee chart tee7100.bpl"版本的旧TeeChart BPL或DCP文件.

我已经运行了teechart附带的"recompile.exe"向导,在向tee.inc文件写入{$ DEFINE x}声明后,它似乎只运行MSBuild并构建包(源代码中有两个)分配).

但是,不知何故,似乎默认情况下,其中一个隐式导入到其中一个软件包中的是一些尚未重建的过时文件,因此会尝试加载tee7100.bpl.新的bpl名称是tee911.bpl.

而不是问一些非常具体的快速报告问题,我只是提到它是一个特定的伤害世界的例子,我在Delphi开发时遇到了几十次.

我只给出了快速报告的详细信息,这样你就可以看到这实际上是一个普通问题的特定实例,当处理组件源代码或包或带有依赖关系的包时,有时会在Delphi IDE中面临这个问题. .清理您的计算机,以便您的代码甚至构建可能是棘手的.

所以这是我的Delphi包到包依赖解析问题:

  1. 找到或跟踪隐藏加载一些不再需要的BPL问题的最有效方法是什么,这样我的代码(构建和编译就好了!)实际上会加载到Delphi IDE中.运行重新编译产生的BPL文件似乎正确链接到正确的DCP文件,并且不存在旧的/陈旧的DCP或DCU文件.例如,新的DCP文件名是tee911.dcp.

  2. 你能以某种方式得到任何关于什么包实际上是陈旧的,以及在.bpl链接时正在读取和链接以及静态导入的内容吗?(我想可能像BPL文件的特殊MAP类文件?)

更新经过几个小时的战斗,并使用我所知道的每一个技巧,我意识到我没有检查VirtualStore过Windows 7中文件虚拟化引起的一些相关问题.这意味着Windows 7依赖于运行在它上面的程序.它为您提供了该文件的另一个版本,而不是您想要的版本.这在几个方面可能是致命的; 一; 你重新编译了一个BPL,但那不是加载的.杀死我的BPL位于SysWow64文件夹中,该文件夹是VirtualStore的一部分.请注意,虚拟存储基本上会出现幻像文件,只有当你是一个特定的"低级别"程序时才会出现,其中Delphi 2007在Win7/64位上显然是这样.要删除当前用户帐户的SysWow64 VIRTUALSTORE文件夹中的BPL文件,请执行以下操作:

   del %HOMEPATH%\AppData\Local\VirtualStore\Windows\SysWow64\*.bpl
Run Code Online (Sandbox Code Playgroud)

...有些日子我只讨厌Windows架构.无论如何,我不打算将上述内容作为答案,因为我想知道是否有人有更好的方法或任何可能有助于下次的提示或建议.

delphi dependencies bpl

12
推荐指数
1
解决办法
3万
查看次数

如何将Delphi项目正确划分为BPL?

我工作的公司在Delphi中开发了一个系统,它包含许多exe模块,如果涉及源代码,它们在某种程度上是相同的.遗憾的是,没有人关心使用库来共享代码.这意味着每次在代码中都有错误修复所有这些模块共享时,程序员必须分别对所有这些模块进行修正!它总是需要这么多时间......

我决定找到一种方法将共享代码放入库中.我考虑过DLL和BPL.在这种情况下,BPL似乎更方便程序员,更不麻烦,特别是代码仅在我们的软件中使用,并且仅在Delphi中使用.

我将所有exe模块共享的所有代码放入BPL中,一切看起来都很好,但有些事我不明白,如果你向我解释,我将不胜感激.

  1. 在将代码划分为BPL之后我的期望是,使用我创建的BPL部署exe文件就足够了.但事实证明他们也需要一个rtl100.bpl和vcl100.bpl.为什么会这样?我想只部署exes和我的BPL.我不想为最终用户提供由Borland和第三方公司提供的一大堆库:).我希望它们在exes中编译,就像之前编译的那样.有可能吗?

  2. 到目前为止我做的是:

    • 我把所有共享的pas单位都放到BPL上.每个BPL包含属于同一类别的单元,因此程序员可以清楚地了解给定BPL中的代码.
    • 每个BPL都是"运行时和设计时"库.
    • 每个BPL都是"明确重建".后两者是BPL的默认项目设置.
  3. 如果涉及到exe项目:

    • 我删除了我之前提交给BPL的所有单位.
    • 我在BDS 2006的Tools-> Install package菜单中安装了我的BPL.
    • 在我的exe项目设置中,我选中了"使用运行时包构建"选项,并在下面的编辑框中列出了我的所有BPL包(仅限我的包,因为我清除了那里出现的所有其他包).

这就是我所做的一切.exe项目编译正确,但我无法访问BPL的源代码(我无法从我的exe项目导航到该代码),即使所有BPL与其源代码文件一起存储.为什么?这对我来说似乎很奇怪.

我总是倾向于写冗长的描述 - 抱歉:).我将感谢你的帮助.我只需要对我提到的要点进行一些解释:仅使用我的BPL部署exe,我作为一个整体做的正确性,以及无法导航到BPL源代码.非常感谢你提前!


谢谢大家的讨论.有人说我选择的方法并不是一个好主意.我们的软件包含100多个模块(大多数模块类似于不同设备的驱动程序).他们中的大多数共享相同的代码 - 在大多数情况下是类.问题是这些类并不总是放在单独的独立的pas单元中.我的意思是共享代码通常放在包含特定于模块的代码的单元中.这意味着当您修复共享类中的错误时,仅将定义的pas单元复制到所有软件模块并重新编译它们是不够的.不幸的是,您必须将固定的代码片段逐个复制并粘贴到每个模块中,并将其粘贴到适当的单元和类中.这需要花费很多时间,这是我想要消除的,选择正确的方法 - 请帮助我.

我认为使用BPL是一个很好的解决方案,但它有一些缺点,正如你们有些人提到的那样.最糟糕的问题是,如果每个EXE需要几个BPL,我们的技术支持人员将不得不知道哪个EXE需要哪个BPL,然后为最终用户提供适当的文件.只要我们没有软件更新程序,这对我们的技术人员和最终用户来说都是一个很大的优势.他们肯定会迷茫和愤怒: - /.

兼容性问题也可能发生 - 如果一个BPL由许多EXE共享,一个BPL的修改对于一个EXE是好的而对另一个也是坏的 - @Warren P.

那么我应该怎么做才能在这么多项目中更快地修复错误?我想到了以下方法之一.如果您有更好的想法,请告诉我.

  • 将共享代码放入单独的独立的pas单元中,因此当其中一个错误修复时,将其复制到所有项目(覆盖旧文件)并重新编译所有项目就足够了.

只要修改了后面修改的代码,这个解决方案似乎就可以了.但是我们也有具有一般使用功能和程序的通行单元,这通常是不可修改的 - 我们在必要时在那里添加新功能,但是在单个项目中.因此,假设您在100个模块中的一个模块中编写了一个新函数,并将其放入其通用单元中.一两个月之后,您修改了一个不同的模块,您认为您需要在2个月前编写的相同功能.您必须找到该模块(如果您不记得它是哪个模块很困难)并将该功能复制到您的代码中.显然 - 只要每个模块中的一般使用单元分别存储在每个模块中,它们就会完全不同.然后,如果有一个错误修复要做...整个故事重复.

  • 为所有共享代码创建BPL,但将它们链接到EXE,以便EXE是独立的.

对我来说,这似乎是现在最好的解决方案,但有几个缺点.如果我在BPL中修复错误,每个程序员都必须更新他们计算机上的BPL.如果他们忘了怎么办?但是,我认为这是一个小问题.如果我们负责通知对方有关变化,一切都应该没问题.

  • @CodeInChaos:我不知道我是否理解你.你的意思是在项目之间共享pas文件?怎么做?我们在SVN中存储源代码.这意味着我们必须将共享代码存储在单独的文件夹中,并使所有项目在那里搜索该代码,对吧?并从SVN下载一个项目及其依赖的所有文件夹......

请帮我选择一个好的解决方案.我只是因为一种愚蠢的软件开发方法,我不希望公司因错误修正而损失更多的时间和金钱.

非常感谢你.

delphi bpl

11
推荐指数
2
解决办法
3293
查看次数

Delphi中模块化编程的最佳方法

这是我在这里开始的讨论的延续.我想找到模块化Delphi源代码的最佳方法,因为我在这个领域没有经验.我将感激你的所有建议.

让我发布我在那里写的内容.

我工作的公司开发的软件包含100多个模块(大多数模块类似于不同设备的驱动程序).他们中的大多数共享相同的代码 - 在大多数情况下是类.问题是这些类并不总是放在单独的独立PAS单元中.我的意思是共享代码通常放在包含特定于模块的代码的单元中.这意味着当您修复共享类中的错误时,将其定义的PAS单元复制到所有软件模块并重新编译它们是不够的.不幸的是,您必须将固定的代码片段逐个复制并粘贴到每个模块中,并将其粘贴到适当的单元和类中.这需要花费很多时间,这是我希望通过选择正确的方法在最近的将来消除 - 请帮助我.

我认为使用与EXE一起分发的BPL将是一个很好的解决方案,但它有一些缺点,正如前面讨论中提到的那些.最糟糕的问题是,如果每个EXE需要几个BPL,我们的技术支持人员将不得不知道哪个EXE需要哪个BPL,然后为最终用户提供适当的文件.只要我们没有软件更新程序,这对我们的技术人员和最终用户来说都是一个很大的优势.他们肯定会迷茫和愤怒: - /.

此外,还可能出现兼容性问题 - 如果许多EXE共享一个BPL,则对该BPL的修改可能对一个EXE有利,对另一个EXE则有害.

那么我应该怎么做才能在这么多项目中更快地修复错误?我想到了以下方法之一.如果您有更好的想法,请告诉我.

  • 将共享代码放入单独的独立PAS单元中,因此当其中一个中存在错误修复时,将其复制到所有项目(覆盖旧文件)并重新编译所有项目就足够了.这意味着每个单元的复制次数与其使用的项目数相同.

就很少修改的代码而言,这个解决方案似乎没问题.但我们也有具有一般使用功能和程序的通行单元,这些功能和程序经常进行修改.每次有人向此文件添加新功能时,都不可能执行相同的程序(复制和重新编译这么多项目).

  • 为所有共享代码创建BPL,但将它们链接到EXE,以便EXE是独立的.

对我来说,这似乎是现在最好的解决方案,但有一些缺点.如果我在BPL中修复错误,每个程序员都必须在他们的计算机上更新BPL.如果他们忘记那样做怎么办?但是,我认为这是一个小问题.如果我们负责通知对方有关变化,一切都应该没问题.你怎么看?

  • CodeInChaos建议的最后一个想法(我不知道我是否理解它).在项目之间共享PAS文件.这可能意味着我们必须将共享代码存储在一个单独的文件夹中,并让所有项目在那里搜索该代码,对吧?每当有必要修改项目时,我想必须从SVN下载共享文件文件夹.共享代码中的每个更改都必须导致重新编译使用该代码的每个项目.

请帮我选择一个好的解决方案.我只是因为一种愚蠢的软件开发方法,我不希望公司在错误修正方面损失比必要的更多的时间和金钱.到目前为止,没有人关心它,你可以想象它会导致多少问题.

非常感谢你.

delphi bpl modularization

11
推荐指数
1
解决办法
2312
查看次数

Delphi:带内置软件包的.exe:600kb,.exe +外部BPL:6MB.这是为什么?

如果我使用内置包在delphi中编译.exe文件,它会生成大约600kb的EXE文件.但是,如果我使用运行时包编译它,大小的总和(.exe +所有必需的.BPLs)大约是6-8 MB(取决于编译器的版本).为什么差异如此显着?

delphi exe bpl

9
推荐指数
1
解决办法
521
查看次数

Delphi - BPL中的unmangle名称

是否有可能在Delphi中取消这些名称?如果是这样,我在哪里可以获得更多信息?

它无法在dbrtl100.bpl中找到某个条目的错误消息示例我想知道它找不到哪个确切的函数(单位,类,名称,参数等).

---------------------------
myApp.exe - Entry Point Not Found
---------------------------
The procedure entry point @Dbcommon@GetTableNameFromSQLEx$qqrx17System@WideString25Dbcommon@IDENTIFIEROption could not be located in the dynamic link library dbrtl100.bpl. 
---------------------------
OK   
---------------------------
Run Code Online (Sandbox Code Playgroud)

我知道它是Dbcommon单元中的GetTableNameFromSQLEx方法(我有Delphi和RTL/VCL源代码),但有时我会遇到并非所有代码都可用的应用程序(是的,客户应该总是购买第三方的所有源代码)东西,但有时他们没有).

但是说这是一个我没有代码的例子,或只有接口文件(BDE.INT任何人?)它有什么参数(即哪个潜在的重载)?它有什么回报类型?

对于任何Delphi版本,这种破坏是否相同?

--jeroen

编辑1:

感谢Rob Kennedy:tdump -e dbrtl100.bpl可以解决问题.根本不需要-um:

C:\WINDOWS\system32>tdump -e dbrtl100.bpl | grep GetTableNameFromSQLEx
File STDIN:
00026050 1385 04AC __fastcall Dbcommon::GetTableNameFromSQLEx(const System::WideString, Dbcommon::IDENTIFIEROption)
Run Code Online (Sandbox Code Playgroud)

编辑2:

感谢TOndrej发现了这篇德语EDN文章(英文谷歌翻译).那篇文章非常准确地描述了格式,应该可以创建一些Delphi代码来解决这个问题.

Pitty,作者提到的网站(和电子邮件)现在已经死了,但很高兴知道这些信息.

--jeroen

delphi bpl name-mangling

9
推荐指数
3
解决办法
1955
查看次数

如何从可执行文件中调用bpl中的Delphi函数?

我有一个Delphi应用程序,我已经编写了一个相当简单的包装器.exe for.

基本上,有一个dll有一堆函数,其中一个我会在我的包装器完成所需的操作后迭代调用.我无法控制这个dll文件,永远不会.

好吧,现在这个DLL是BPL,我不知道如何在该文件中调用函数.提前致谢.

delphi bpl

8
推荐指数
1
解决办法
4012
查看次数