什么会导致不匹配的 DCU 文件?

What could cause a mismatched DCU file?

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

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

当我打开我的项目并先编译它,然后双击该文件时,一切正常。

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

(1) 我们的应用程序还在生产中表现出以下行为:它有时会在继续使用稳定的 cpu 用法时崩溃,或者只是继续按预期工作但在 cpu 中显示稳定的用法的背景。我们一直无法在编译版本中触发它,但会时不时地看到它弹出。我们假设 dcu 不匹配是此问题的根源。

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

在项目组 window 中,右键单击该项目并 select 构建。

删除项目中的所有 DCU 是可以的,但不是必需的(或者可取,以防出错...)。

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

你的问题中有很多问题,有些完全不相关,但问题是 "mismatched" DCU 的假设不太可能是正确的(我认为你的意思是 "old" 或否则,过去或使用不同来源编译的 DCU 不正确)。

首先是你的问题。

IDE 行为

在项目管理器中双击一个单元时 IDE 锁定的问题不太可能与 "mismatched" DCU 有任何关系。

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

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

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

至于为什么它在使用 F12 而不是项目管理器时会有不同的行为,不幸的是 Delphi IDE 因在不同的地方使用不同的机制来实现相同的事情而臭名昭著,所以它不是令人惊讶的是,有时当其中一种机制中断时,其他机制仍然有效(即使两者都有效,也会产生不同的结果)。

您应用的运行时行为

如果我们在您确实拥有 "mismatched" DCU 的基础上工作,那么只要您拥有所有必需的 DCU 的源代码,那么执行项目的完整构建将解决该不匹配问题每个 DCU 的正确适当来源可用。

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

DCU 是 "mismatched" 的简单事实不会导致异常的应用程序行为。除了 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

构建中编译了什么?

当您对项目执行 Build 时(与 "Compile" 不同),该项目引用的所有单元都将被重新编译,任何单元除外VCL/RTL 个单位(即 Delphi 提供的单位)。那些得到特殊待遇。

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

注意:DCU 缺少源

一个单元只会被重新编译如果 可以找到源码.

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

即使满"Build"也是如此。

第 3 方 DCU

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

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

问题 2:我应该删除所有 DCU 吗?

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

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

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

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

可能发生了其他答案中未解决的三件事。
请注意,我只有 Delphi XE2 和 Seattle 10 的经验,但它们可能适用于您的版本。

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

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

  4. 条件编译。如果你的代码中有 IFDEF 为一个项目编译东西但没有为另一个项目编译东西,你的 IDE 可能会完全挂起,而且你无能为力然后杀死 BDS.EXE。如果您切换项目并且不小心 Compile 而不是 Build.

    [=28=,就会在 Delphi Seattle 10 发生这种情况]

您可能会遇到这些变化。