【问题标题】:Custom component dependency hell自定义组件依赖地狱
【发布时间】:2012-04-08 20:30:18
【问题描述】:

我正在尝试为我制作的自定义组件制作一个包。它基于多个库,包括 Graphics32、GraphicEx 和 CCR.Exif。

我创建了一个 Package 项目,编写了包含其注册过程的单元,添加了一些 Delphi 通知我的额外参考到 requires 部分(包括 dbrtl.dcp、inet .dcp、soaprtl.dcp、vclimg.dcp、xmlrtl.dcp 和 dclGraphicEx140.dcp),并在 contains 部分添加了许多单位,以避免隐式发生有关它的警告。该项目可以编译并且可以在我自己的机器上安装和使用而不会出现问题。但是,当我想在另一台机器上安装它时,麻烦就开始了。最后,我不得不从我使用的所有第 3 方组件中复制所有 DCU,以及来自 GraphicEx 的 DCP 和 BPL,我什至必须安装它们。

提供大量文件很麻烦,但可以克服,但必须同时安装其他软件包是不行的。我可以通过在 contains 部分中放置更多单元来摆脱 DCP 和 BPL,但这会导致在我自己的实际安装了 GraphicEx 的机器上出现错误消息。这让我很困惑,因为 Graphics32 不会发生这样的事情......

无论如何,我如何将我的分发量保持在最低限度并避免这种情况?我希望我团队中的其他开发人员能够使用该包,而不必担心我用来构建它的内容。首先,不能将所有 3rd 方单元都编译到我自己的 DCU 中吗?

【问题讨论】:

  • 组件安装是 Delphi 的耻辱,现在 Embarcadero 经常忽略。
  • 你正在做什么样的分发,给编译应用程序的用户或其他开发人员以便他们在 IDE 中使用?
  • 我同意@Serg。当我需要部署依赖的组件时,我总是想上吊。我什至从不费心创建包。我在运行时加载了我的大部分组件以避免那个噩梦......
  • 那么第 3 方组件开发人员是如何做到这一点的呢?他们总是只使用 VCL 吗?!我无法想象最好的解决方案是将所有使用过的单位手动复制到我自己的,然后将它们从 uses... 中删除
  • @tvdien,我见过的大多数第 3 方 VCL 仅依赖于“本机”VCL/RTL,除非他们使用 众所周知 其他第 3 方组件 作为选项比如“TNT”(通常是编译器指令选项)或者需要添加PNG支持(所以他们使用PngImage作为选项),或者基于VST等等等...当然这一切都取决于 Delphi 版本,因为大多数知名的 3rd 方组件(非商业组件)现在都集成在较新版本的 Delphi(即 XE/2)中。

标签: delphi delphi-2010 custom-component graphicex


【解决方案1】:

对于编写组件的人来说,您所经历的都是平常的事情。分布总是这样。包不携带其他包,因为它们引用了它们。这是他们的本性。

为了克服这种情况,我总是像对待要出售的产品一样对待我的组件:我构建了一个设置向导,用于分发和注册软件包所需的所有内容。

就我而言,InnoSetup 运行良好 (http://www.jrsoftware.org/isinfo.php)。

【讨论】:

  • 你如何检查一个包是否还没有安装(因为你不能安装两次)?没有一个固定的位置可以期待它。
  • @ThijsvanDien:在 IDE 中注册的所有包都列在 Windows 注册表中的HKEY_CURRENT_USER\Software\Embarcadero\BDS\7.0\Known Packages 下。 BDS 版本取决于 Delphi 版本。如果我没记错的话,7.0 表示 Delphi 2010。查看该键下的项目以确定某个包是否已存在于 IDE 中。
【解决方案2】:

总结

有一段时间没有使用 Delphi,但是,确实开发了我的自定义可视化控件(我工作的最后一个版本是 Delphi 6)。

在处理包依赖时有两个问题。一种是在 Delphi 环境中安装,使控件出现在组件面板上,另外还有组件编辑器和属性编辑器。

另外一个是将编译好的包分发到客户机器时。

这还取决于您在 Delphi 上运行的版本。

设计时间

开发自定义包时,有一个包选项选项卡,指示目标文件夹。

手册通常会告诉开发人员将这些文本框留空。这有时有效,有时无效。我明确地在各自的文本框中写下每个文件夹路径。

.dcp”文件有一个文本框路径,“.dcu”文件有一个文本框路径,以此类推。

如果您有可视控件和属性编辑器或组件编辑器之类的东西,最好将代码拆分为 2 个包(“运行时”和“设计时”)。

我通常把delphi(packages)项目放在delphi安装文件夹之外。

运行时间

通常,快速的方法是将“*.bpl”“.dcp”文件放在Windows(32)/系统文件夹,或类似的“DLL”windows文件夹中。


Packages文件夹结构源码建议

管理包可能很困难。我不知道 Embarcadero 和较新版本的 Delphi 对安装过程的影响有多大。下图是如何组织源代码的示例。希望对您有所帮助。

[-]--+--c:
.....|
.....+--[-]--+--software
.............|
.............+--[+]-----java
.............|
.............+--[+]-----php
.............|
.............+--[-]--+--delphi (not the delphi folder in program files)
.....................|
.....................+--[+]-----apps (source code for delphi programs)
.....................|
.....................+--[+]-----other
.....................|
.....................+--[-]--+--packages (all delphi packages source code here)
.............................|
.............................+--[+]-----lib (a single package for non visual controls, libraries)
.............................|
.............................+--[+]-----tools (package pair for non visual tcomponent descendants)
.............................|
.............................+--[+]-----json (example)
.............................|
.............................+--[+]-----xml (example)
.............................|
.............................+--[-]--+--mycontrols (folder custom visual controls)
.............................|.......|
.............................|.......+--[-]--+--delphi40 (folder for delphi40 version of "mycontrols")
.............................|.......|.......|
.............................|.......|.......+----------dsgvclctrls40.dpk (design-time package "mycontrols")
.............................|.......|.......|
.............................|.......|.......+----------runvclctrls40.dpk (run-time package "mycontrols")
.............................|.......|.......|
.............................|.......|.......+--[+]--+--demos (individual example for each "mycontrol")
.............................|.......|.......|
.............................|.......|.......+--[+]--+--design ("*.pas" component editors  destination folder)
.............................|.......|.......|
.............................|.......|.......+--[+]--+--sources ("*.pas" source code destination folder)
.............................|.......|.......|
.............................|.......|.......+--[+]--+--bin ("*.dcu" destination folder)
.............................|.......|........
.............................|.......+--[+]--+--delphi50 (folder for delphi50 version of "mycontrols")
.............................|.......|........
.............................|.......+--[+]--+--delphi60 (folder for delphi60 version of "mycontrols")
.............................|.......|........
.............................|.......+--[+]--+--delphi70 (folder for delphi70 version of "mycontrols")
.............................|................
.............................+--[-]-----etc...

干杯。

【讨论】:

  • 抱歉,但我不明白这如何回答我关于如何以用户(开发人员)不必采取特殊措施(下载/安装依赖项,以特定方式组织他的项目)来使用它。
  • “设计时间”是实现目标的前一步。 “运行时”更倾向于分发。
【解决方案3】:

Thijs,你不能只用一个包来做到这一点。目标开发人员将需要您添加到包中的几乎所有内容。但是有另一种方法可以做你想做的事:用你在自己的组件中使用的所有组件/库构建一个 DLL,并将所有这些外部组件/库包装到一些你将从 DLL 导出的代码中。然后在不直接使用外部组件的情况下构建您的组件,而是使用您构建的 DLL。您不能在您的组件中“使用”其他外部组件/库的任何单元。您必须为从 DLL 导出的任何内容构建一个包含所有数据类型和所需声明的新单元。所有这一切都完美无缺,但对于大量外部组件或库来说很快就会变得非常复杂。

【讨论】:

  • 我可以使用 BPL 代替 DLL 来使用对象吗?是不是可以将 BPL 编译到 exe 中?
【解决方案4】:

我认为 AlexSC 有最好的答案,但如果您绝对必须拥有一个没有依赖关系的自定义组件,我认为可能还有其他选择。

我在尝试为我们的开发人员创建内部组件时遇到了 Delphi 依赖问题。我的建议:

  1. 卸载组件使用的所有依赖项

  2. 在您的组件包中,从您的包的 requires 部分中删除上述 dcp。

  3. 将依赖项的源文件复制到组件中

当您分发组件时,您必须使用所需依赖项的代码分发它

如果您想单独使用依赖项,您会遇到问题,因为 Delphi 不允许您在已安装的包中有重复的单元名称。

此外,您不想使用 DCU 的原因是 DCU 是针对特定平台和编译器编译的。因此,除非您确定所有 devolper 都在使用相同版本的 Delphi 的同一平台上,否则需要重新编译依赖代码。

同样,AlexSC 有最好的答案,而 InnoStudio 是一个很棒的小工具。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 2021-07-16
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多