我们一直在修复Delphi XE6中VCL的漏洞。目前,该文件夹包含:
| VCL Source Fixes
|----- Vcl.ComCtrls.pas
|----- Winapi.CommCtrl.pas
我们将该文件夹添加到我们的库搜索路径中:
在此过程中,我们学到了我们必须仅限于implementation
部分修复问题。 否则,interface
部分中符号的哈希签名会发生更改。 这会导致链接器意识到DCU内的符号不是他们所期望的相同版本。
Barry Kelly 对此行为进行了很好的解释:
重要的概念是符号版本。在保存DCU时,Delphi基于符号的接口声明计算哈希并将其与符号关联起来。使用符号的其他单元也存储符号版本。通过这种方式,可以避免因陈旧符号引起的链接时间冲突,这与大多数C语言链接器不同。
由此产生的结果是,您应该能够将Classes.pas添加到项目中并几乎尽情修改其implementation部分,并且仍然能够与RTL和VCL及提供的仅以对象格式提供的第三方库进行静态链接。
需要注意的事项:
- 内联例程; 内联例程的主体是符号版本的一部分
- 泛型; 通用类型和方法的实现方面是相应符号版本的一部分
因此,我们费心将错误修复限制在实现部分(例如,引入新的破解器类而不是覆盖公共类中的方法)。
然后
然后我去修改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
为什么会发生这种情况?
重要的问题是:
为什么会发生这种情况?
为什么编译器无法意识到完全相同的文件是完全相同的文件?VCL源代码是否与XE6附带的DCUs不匹配?这是否与库搜索顺序有关?是否与内联、泛型、迭代器、平台、调试DCUs、64位编译器、ifdefs、代码完成、协同作用、超越常规思维有关?
解答“为什么”的其他隐含问题包括:
为什么对于另外两个文件它能正常工作,但对于这一个却失败了?
为什么即使我并没有更改文件,它也会出错?
你尝试了什么?
- 尝试在搜索路径中将
VCL Source Fixes
上移或下移 - 尝试打开Use debug dcus
- 尝试切换到64位平台
- 尝试删除我的项目文件夹中的所有
dcu
文件(但没有删除随Delphi XE6一起发行的D:\Programs\Embarcadero\Studio\14.0\lib\win32\release\Vcl.Themes.dcu
) - 关闭XE6并重新运行它
- 去Wendy's吃午餐
当然,我想要解决它。但更重要的是,我想了解为什么它失败了。编译器没有使用魔法、巫术或Q式力量。它是一个确定性机器,并根据一组固定的(未记录的)规则操作。
为什么会发生这种情况?
Ctrl+O+O
将“标准”编译器选项插入替换后的pas文件顶部。这就是为什么我要在这里回答它:这样就有了一个答案,而不是随机的跌跌撞撞。 :) - Ian Boyd