2014-08-28 116 views
10

我们一直在Delphi XE6中修复VCL中的错误。到目前为止,该文件夹包含:F2051:单元%s是使用不同版本的%s编译的

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

而且我们的文件夹添加到我们的图书馆搜索路径:

enter image description here

一路上,我们了解到,我们必须集中我们修复的implementation部分只有。否则,interface部分中的符号的散列签名会改变。这会导致链接器意识到DCU中的符号与他们期望的不同。

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

重要的概念是符号版本。当保存一个DCU时,Delphi根据该符号的接口声明来计算散列,并将其与该符号相关联。其他使用符号的单位也存储符号版本。通过这种方式,避免了由过时符号引起的链接时冲突,与大多数C链接器不同。

这样做的结果是,你应该能够Classes.pas几乎添加到您的项目并修改其实施节你的心脏的内容,并且仍然能够静态链路与RTL其余以及VCL和第三方库,甚至那些仅以对象格式提供的库。

事情要小心:

  • 内联例程的;内联例程的主体是符号版本的一部分
  • 泛型;泛型类型和方法的实施方是各自的符号版本

所以我们煞费苦心地限制了错误修正,以实现部分(如引入新的饼干类,而不是覆盖方法在公众的一部分面向类)。

然后

然后我去,使修复的Vcl.Themes.pas。我从简单的开始,复制文件,并把它在修复文件夹:

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

即使我没有(还)甚至修改Vcl.Themes.pas,编译器扼流圈它:

[dcc32致命错误] Vcl.Themes.pas(2074):F2051单元Vcl.Forms是用不同版本的Vcl.Themes编译的。TMouseTrackControlStyleHook

为什么

重要的问题是:

这究竟是为什么?

这是怎么回事编译器无法意识到完全相同的文件是完全相同的文件? XE6附带的VCL源码可能不合适,并且与DCU中的船只不符?它与图书馆搜索顺序有关吗?它是否与内联,泛型,迭代器,平台,调试dcus,64位编译器,ifdefs,代码完成,协同作用有关?

还有其他的,隐含的,问题是,试图回答走的为什么

为什么它对于其他两个文件的工作,但没有这一项?
为什么当我甚至没有更改文件时会失败?

你有什么试过的?

  • 尝试移动搜索路径
  • 试图打开使用调试的DCU
  • VCL Source Fixes较高和较低的尝试切换到64位平台
  • 试图删除在我的项目的文件夹中的所有dcu文件(虽然不删除附带Delphi XE6的D:\Programs\Embarcadero\Studio\14.0\lib\win32\release\Vcl.Themes.dcu
  • 关闭XE6并重新运行它
  • 要去到温迪的午餐

当然我想解决它。但不止想解决它,我想了解它为什么失败。编译器没有使用魔法,巫术或类似Q的权力。这是一个确定性的机器,并且按照一套固定的(无证)规则进行操作。

这是怎么发生的?

+1

嗯,这让我们两个人去了温迪的午餐:-) – 2014-08-28 17:54:52

+0

请参阅[德尔福 - 在修复VCL错误时,Unit x是用不同版本的x编译的](http://stackoverflow.com/ q/24412299/576719)和[我可以在RTL类System.Classes.TStream中修改一个常量,并在Delphi XE6的运行时重建它?](http://stackoverflow.com/q/24145214/576719)。请参阅@DavidHeffernan的答案。巫术是。 – 2014-08-28 17:57:20

+1

对不起伊恩,但你运气不好。你需要绕道。我试图说服马可,这是坏的,但他不相信我。 http://blog.marcocantu.com/blog/2014_august_buffer_overflow_bitmap.html marco的意思是成为开发关系的人,所以上帝帮助我们,当他不会听我们的时候 – 2014-08-28 18:19:14

回答

7

看到你所需要的编译器选项,以匹配当单位被Embarcadero公司编制使用。这就是为什么你的实现部分只有在它看起来应该成功时才会失败。

启动默认的项目并使用CTRL +Ø+Ø产生这些选项。我得到

{$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+} 

就够了。

相关问题