delphi - F2051 : Unit %s was compiled with a different version of %s

标签 delphi delphi-xe6

我们一直在修复 Delphi XE6 中 VCL 中的错误。到目前为止,该文件夹包含:

| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas

我们将该文件夹添加到我们的搜索路径中:

enter image description here

在此过程中,我们了解到必须将修复仅限于实现部分。否则,interface 部分中符号的哈希签名会发生变化。这会导致链接器意识到 DCU 内的符号与它们期望的版本不同。

Barry Kelly对于这种行为有一个很好的解释:

The important concept is that of symbol version. When saving a DCU, Delphi calculates a hash based on the interface declaration of the symbol and associates it with the symbol. Other units that use the symbol also store the symbol version. In this way, link-time conflicts caused by stale symbols are avoided, unlike most C linkers.

The upshot of this is that you should be able to add Classes.pas to your project and modify its implementation section almost to your heart's content, and still be able to statically link with the rest of the RTL and VCL and third-party libraries, even those provided in object format only.

Things to be careful of:

  • Inlined routines; the body of inlined routines are part of the symbol version
  • Generics; the implementation side of generic types and methods are part of the respective symbol versions

因此,我们煞费苦心地将错误修复限制在实现部分(例如引入新的破解类,而不是覆盖面向公众的类中的方法)。

然后

然后我在Vcl.Themes.pas中进行了修复。我从简单的开始,复制文件并将其放入修复文件夹中:

| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas
|----- Vcl.Themes.pas

尽管我还没有修改 Vcl.Themes.pas,但编译器却卡住了:

[dcc32 Fatal Error] Vcl.Themes.pas(2074): F2051 Unit Vcl.Forms was compiled with a different version of Vcl.Themes.TMouseTrackControlStyleHook

为什么

重要的问题是:

Why is this happening?

编译器无法识别完全相同的文件是完全相同的文件,这是怎么回事? XE6 附带的 VCL 源代码是否有可能不正确,并且与 DCU 中附带的内容不匹配?它与图书馆检索顺序有关吗?它与内联、泛型、迭代器、平台、调试 dcus、64 位编译器、ifdef、代码完成、协同、开箱即用有关吗?

在尝试回答原因时,还有其他隐含的问题:

Why does it work for two other files, but not this one?
Why does it fail when I didn't even change the file?

你尝试过什么?

  • 尝试在搜索路径中移动 VCL 源代码修复 的位置
  • 尝试打开使用调试 dcus
  • 尝试切换到 64 位平台
  • 尝试删除项目文件夹中的所有 dcu 文件(但未删除 D:\Programs\Embarcadero\Studio\14.0\lib\win32\release\Vcl.Themes.dcu 随 Delphi XE6 一起提供)
  • 关闭 XE6 并重新运行
  • 去温迪餐厅吃午饭

我当然想修复它。但除了想要修复它之外,我还想了解它失败的原因。编译器不使用魔法、巫毒或类似 Q 的能力。它是一台确定性机器,并且根据一组固定的(未记录的)规则进行操作。

为什么会发生这种情况?

另请参阅

最佳答案

您需要编译器选项来匹配 Embarcadero 编译该单元时使用的选项。这就是为什么你的实现部分只有在看起来应该成功时才会失败。

启动默认项目并使用 CTRL + O + O 生成这些选项。我明白

{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N-,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}

当我在 XE6 中执行此操作时。

把它放在你的单元副本的顶部,你就可以开始了。根据您的宿主项目选项,您可能可以使用其中的一个缩减子集。在我的代码中我发现:

{$R-,T-,H+,X+}

够了。

关于delphi - F2051 : Unit %s was compiled with a different version of %s,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25555009/

相关文章:

delphi - 如何让 Delphi 2009 默认在第二个显示器中打开我的应用程序?

delphi - 将整数值转换为枚举类型

android - delphi xe6 firemonkey 更改表单样式运行时

delphi - 在 Delphi 中有效地将整数与静态整数列表进行比较?

delphi - 在delphi中测试泛型的类型

delphi - Delphi 中组件的定位提示

delphi - 六角格计算

arrays - `System.CopyArray` 与 `System.Copy` ?

delphi - `First` 应该总是在查询的 `Open`/`TDataset` 之后被调用吗?

delphi - 如何在TThread中设置堆栈大小?