gpt4 book ai didi

delphi - 如何修补 TControlCanvas.CreateHandle(FreeDeviceContexts 问题)?

转载 作者:行者123 更新时间:2023-12-02 04:59:22 25 4
gpt4 key购买 nike

这个问题与我之前的问题相关:

access violation at address in module ntdll.dll - RtlEnterCriticalSection with TCanvas.Lock

显然 Delphi 的代码中存在一个错误(参见 QC 64898: Access violation in FreeDeviceContexts )。这个错误一直持续到 D2010,AFAIK。

到目前为止,建议的解决方法效果很好。现在我陷入了两难的境地。

我不喜欢在我的项目中使用 Controls.pas 的私有(private)副本 - 我不确定它是否安全。 Controls 单元是一个非常低级别的单元,考虑到我的大型应用程序除了提到的问题之外运行良好,我真的觉得这是一个重大举措。我也不确定是否/如何重建项目中依赖于 Controls 单元的所有组件/单元。

是否可以修补使用内部 CanvasList 和私有(private)成员的 TControlCanvas.CreateHandle()

注意:我将仅将此补丁用于此项目(Delphi 5)。我不介意对偏移量进行硬编码。 AFAIK,修补私有(private)总是使用基于编译器版本的硬编码偏移。我可能能够自己处理私有(private)(没有类助手),但我不知道如何处理CanvasListFreeDeviceContext(),它们在 Controls 单元的实现部分中声明。

最佳答案

正如评论中所讨论的,即使在旧版本的 Delphi 中,也可以访问类的 privateprotected 成员,而无需“类(class)助手”。

但是,本例中的问题围绕特定方法实现的细节,而不仅仅是能够访问或修改私有(private)成员变量。此外,特定方法的实现利用了所涉及单元中的实现变量。特别是您记下的 CanvasList 变量。

即使有类助手的好处,也没有简单的方法来访问该实现变量。

您当前的解决方案是最简单、最安全的方法:使用整个单元的副本,并对解决问题所需的特定方法进行修改。

请放心,这并不是一种罕见的做法。 :)

这种方法的唯一问题是,在建立新的开发环境或升级到新版本的 IDE 时,一定要管理好您所依赖的该单元的“私有(private)化”副本这一事实。

在新的开发环境中,仔细的项目配置应该能够解决问题(当然,修改后的 Controls.pas 单元是版本控制项目的一部分)。

在升级到较新的 Delphi 版本的情况下,您只需记住在每个新版本中重新访问修改后的 Controls 单元,更新项目中的私有(private)副本并重新应用您所做的修改。已酌情作出。在大多数(如果不是全部)情况下,这应该很简单。

但我真的想访问 CanvasList 变量

正如我上面所说,没有简单方法来访问该单元中使用的实现变量(如果您想以某种方式在运行时“修补”代码,则这是必要的,而不是而不是在编译时用修改后的副本替换它)。

但这意味着存在一种**非**简单的方法。确实有。

与应用程序中的任何数据一样,该变量驻留在进程中的某个内存地址。只是编译器作用域规则阻止您直接在源代码中对其进行寻址。没有什么可以阻止您弄清楚如何在运行时找到该位置并通过指针寻址该内存位置,就像您可以访问的任何其他“原始”内存地址一样。

我没有详细演示如何做到这一点,并且强烈建议尝试实现这样的解决方案是浪费时间和精力,因为存在更简单的解决方案(复制和修改单元)。

除此之外,根据确定所涉及内存位置的方法的可靠性,直接访问该内存位置可能不仅容易受到编译器版本之间差异的影响,甚至容易受到编译器设置引起的更改的影响。

就最终结果而言,它并不比复制单元更好,但肯定要困难得多,可靠性也低得多。

关于delphi - 如何修补 TControlCanvas.CreateHandle(FreeDeviceContexts 问题)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41021660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com