我们一直在Delphi XE6中修复VCL中的错误。到目前为止,该文件夹包含:F2051:单元%s是使用不同版本的%s编译的
| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas
而且我们的文件夹添加到我们的图书馆搜索路径:
一路上,我们了解到,我们必须集中我们修复的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的权力。这是一个确定性的机器,并且按照一套固定的(无证)规则进行操作。
这是怎么发生的?
也
- Delphi - Unit x was compiled with a different version of x, when fixing a VCL bug
- Can I modify a constant in the RTL class System.Classes.TStream and rebuild it at runtime in Delphi XE6?
嗯,这让我们两个人去了温迪的午餐:-) – 2014-08-28 17:54:52
请参阅[德尔福 - 在修复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
对不起伊恩,但你运气不好。你需要绕道。我试图说服马可,这是坏的,但他不相信我。 http://blog.marcocantu.com/blog/2014_august_buffer_overflow_bitmap.html marco的意思是成为开发关系的人,所以上帝帮助我们,当他不会听我们的时候 – 2014-08-28 18:19:14