【问题标题】:What could cause a mismatched DCU file?什么可能导致 DCU 文件不匹配?
【发布时间】:2016-08-10 13:24:56
【问题描述】:

当我打开我的项目并在项目管理器中双击特定的 pas 文件时,bds.exe 冻结并继续使用 25% 的 cpu。我必须通过 Windows 任务管理器终止该进程。 (1)

当我打开我的项目并在完全相同的文件上按 F12 时,我看到了我之前期望看到的内容,即 pas 文件的内容。

当我打开我的项目并先编译它,然后双击文件,一切都很好。

我试图弄清楚我认为不匹配的 DCU 文件是如何潜入我的项目的,以及防止将来出现类似问题的最佳方法是什么。我可以强制重建所有 DCU 文件吗?我可以简单地删除所有 dcu 文件并重新编译还是这样做很危险?我的 DCU 文件目前也存储在我保存 pas 和 dfm 文件的同一目录中,这有点乱。

(1) 我们的应用程序还显示了在生产环境中有时会崩溃的行为,但它会继续使用稳定的 cpu 使用率,或者只是继续按预期工作但在后台显示稳定的 cpu 使用率。我们一直无法在编译版本中触发它,但会不时看到它弹出。我们假设 dcu 不匹配是这个问题的根源。

【问题讨论】:

  • 你还在像三年前一样使用 XE 吗?在以后的帖子中,您从未指出您使用哪个版本。重点是,您是否从早期版本的 Delphi 升级了项目?这可能会带来问题。您可以通过选择“构建”而不是“编译”来构建自己制作的所有 DCU。项目经理有一个“清理”菜单,用于删除所有 DCU。您也可以手动进行。请确保不要删除任何库 DCU 文件。
  • 我还在 XE 上,因此最近没有升级我的项目。
  • 这里没有证据表明“不匹配的 DCU”是问题所在。事实上,我不知道不匹配的 DCU 是什么。无论您的应用程序有什么问题,您都需要对其进行调试以取得进展。添加 madExcept 并在您的应用处于非终止循环时使用 madTraceProcess 提取堆栈跟踪等。

标签: delphi delphi-xe


【解决方案1】:

您的问题中有很多问题,其中一些完全不相关,但假设问题是“不匹配”的 DCU 不太可能是正确的(我认为您的意思是在过去或不同来源)。

首先是你的问题。

IDE 行为

在项目管理器中双击单元时 IDE 锁定的问题不太可能与“不匹配”的 DCU 有关。

您有位于网络驱动器上的源文件吗?这个单位是这样的文件吗?该网络位置是否可用/有效?即文件的路径是否使用不再映射或不可用的网络驱动器号?

如果 DPR 中的单元引用中没有明确的路径,您的系统、IDE 或项目 PATH 中是否列出了网络位置?

难以访问文件位置是 IDE 在尝试简单打开文件时出现锁定的最可能解释。

至于为什么在使用 F12 而不是项目管理器时它的行为会有所不同,不幸的是,Delphi IDE 因使用不同的机制在不同的地方实现相同的事情而臭名昭著,所以有时当使用其中一种机制时,这并不奇怪打破其他仍然有效(即使两者都有效,也会给出不同的结果)。

应用的运行时行为

如果我们的工作是基于您确实有一个“不匹配”的 DCU,那么只要您拥有所有必需 DCU 的源并且 为每个 DCU 提供正确的适当的源。

但是,即使不匹配问题可能得到解决,重建也可能会或可能不会解决问题,这取决于重新编译时该问题是否仍然存在于该单元本身的源代码中。

DCU“不匹配”这一简单事实不会导致异常的应用程序行为。除了 OS 或 RTL 错误等,如果应用程序的行为存在错误,那么这些错误将是编译时源代码中的错误的结果。

简单地重新编译包含错误的源代码不会消除该错误。

因此,如果有这样的错误,那么如果有人能够在该分数上提供任何帮助,则需要更多信息(这应该是一个单独的问题,一旦你自己进行了一些初步调试和诊断)。

运行时包

如果您使用的是运行时包,那么事情会变得更加复杂,因为使用运行时包时,用于任何特定单元的 DCU 都可能是包文件的一部分。在这种情况下,磁盘上的 DCU 文件是在编译包本身时生成的,但是使用的任何项目不会 使用磁盘上的 DCU,但将使用已编译到包中的版本。

因此,如果您正在使用运行时包,那么除了重建您的项目之外,您还需要重建所有可能已更改的运行时包。

现在,针对您的实际问题。

Q1:我可以重建所有的 DCU 吗?

是的,当然。但是请参阅上面的 w.r.t Runtime Packages如果您的项目使用它们。

强烈建议您更改项目设置,将 DCU 文件输出到特定位置,与源文件分开。

例如,您可以拥有一个使用相对路径的项目特定 DCU 文件夹。即将 DCU 输出文件夹设置为“.\dcu”之类的内容,并在 DPR 所在的文件夹中创建一个 dcu 文件夹。

对于支持多个平台和配置的 Delphi 版本,最好在该路径中包含平台和配置的环境变量,这样您就不会在 RELEASE 构建中使用为 DEBUG 编译的单元。

例如

.\dcu\$(Platform)\$(Config)

.\$(Platform)\$(Config)\dcu

构建中编译了什么?

当您对项目执行构建(不同于“编译”)时,该项目引用的所有单元都将被重新编译,但任何 VCL/RTL 单元除外(即那些由 Delphi 提供)。那些会得到特殊待遇。

重建项目至少会强制重新编译 DPR 中明确列出的所有单元,但也会重新编译这些单元(或它们使用的单元等)使用的 所有 其他单元.

注意:DCU 缺少源

一个单元只有会被重新编译如果 源可以被定位

如果您有一个 DCU 并且源文件丢失或无法在项目、IDE 或系统路径上找到,那么编译器将简单地假定您要使用现有的 DCU。

即使是完整的“构建”也是如此。

第三方 DCU

这似乎很明显,但您也应该注意不要删除 DCU,因为它可能是您可能正在使用但没有源代码的任何 3 方库的唯一副本。

这是非常不可取的,但我想我们不能排除您可能处于这种情况的可能性。

Q2:我应该删除所有 DCU 吗?

一般来说,是的。如上所述,如果您缺少引用的单元的源代码,即使完整构建也会成功,只要存在可以找到的 DCU(或所需的包,如果使用运行时包)。

因此,确保您拥有所有 DCU 的当前来源的唯一方法是首先删除任何先前版本可能使用过的 DCU。

当您有一个特定的、明确的位置来输出您的所有项目 DCU 时,这当然会容易得多。

如果您使用的是运行时包会稍微复杂一些,但如果您要合理地组织 DCU,那么唯一真正的复杂情况是您需要重复相同的练习对于所有涉及的项目,通过启动每个使用的运行时包并完成依次使用它们的项目。

【讨论】:

    【解决方案2】:

    是的,您可以重建项目中的所有 DCU 文件;

    在项目组窗口中,右键单击项目并选择构建。

    删除项目中的所有 DCU 是可以的,但不是必需的(如果您犯了错误,也不可取...)。

    请注意,这只会在您的项目中显式构建 DCU(如您的项目树中所示),而不是由于您的 uses 子句而导入的任何隐式 DCU。

    【讨论】:

    • 当然,除非有 DCU 的你没有源代码。这仍然可能是“好的”(如果您没有需要获取它的来源,请找到它或重新创建它,以便找出缺少哪些来源是一件好事)但是可能不是您似乎建议的完全无风险锻炼。例如如果您使用的是无源提供的第 3 方 DCU,则最好在将其吹走之前在某处备份该 DCU。只要可以找到 PAS 源(在系统、IDE 或项目路径上),“构建”也会重新编译隐式使用的 DCU。
    【解决方案3】:

    其他答案中可能没有解决三件事。
    请注意,我只使用过 Delphi XE2 和 Seattle 10,但它们可能适用于您的版本。

    1. 从表单切换到源视图时,Delphi 可能会很慢,尤其是当表单上有很多组件时。在从 XE2 迁移到 10 时,我们注意到这里有所改进。我们在这里谈了几秒钟,这似乎不是你的问题。

    2. 在项目之间切换时,Delphi 的速度非常慢。切换后,IDE 可能需要很长时间(20-30 秒)才能做出响应。你不能输入任何东西;代码完成需要很长时间;使用 Alt-S-D 启动项目搜索会等待很长时间,然后失败。在从 XE2 迁移到 10 时,我们注意到这里出现了很大的恶化。

    3. 条件编译。如果您的代码中有 IFDEF 为一个项目编译内容,但没有为另一个项目编译内容,则您的 IDE 可能会完全挂起,并且除了杀死 BDS.EXE 之外您无能为力。如果您切换项目并意外编译而不是构建,则会在 Delphi Seattle 10 中发生这种情况。

    您可能会遇到这些变化。

    【讨论】:

      猜你喜欢
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      • 2011-07-09
      相关资源
      最近更新 更多