如何在不改变库文件的情况下修改Delphi库文件中的常量?

How to modify a constant in a Delphi library file without changing the library file?

我使用第三方库,我需要为其更改常量。我想自定义库而不覆盖文件。 pas文件是库文件,不是可继承的class.

目前我可以通过编辑文件来实现我的目标

unit libraryconstants;

interface

uses
  System.Types;

const
  constant1 = 'foo';
  constant2 = 32;
  constant3: Integer = 12;
  constant4: TSize = (cx: 32; cy: 32);

我需要像这样更改 constant4

constant4: TSize = (cx: 16; cy: 8);

我可以编辑 libraryconstants.pas 并保存它,但是当我更新库时(因为发布了新版本),我将丢失此更改。当然,我可以在每次更新库时提醒我应用此更改,但我想尽可能避免这种情况。

由于常量未发布 属性 我不知道如何实现所需的结果。我想尽可能少地干扰库代码。

我正在寻找一种 Delphi 语言 "trick" 我不知道。

谢谢。

在项目设置中(CTRL+SHIFT+F11):

Delphi compiler \ Compiling \ Syntax options

将“可分配类型常量”的值更改为 True。 然后你可以将类型化常量修改为常规变量:

constant4.cx := 16;
constant4.cy := 8;

创建一个新的 UNIT:

unit libraryconstantspatch;

interface

implementation

uses System.Types, libraryconstants;

initialization

asm
        mov     eax,offset libraryconstants.constant4
        mov     [eax+offset TSize.cx],16
        mov     [eax+offset TSize.cy],8
end

finalization

end.

然后在应用程序中的 libraryconstants 单元之后的 USES 语句中列出该单元。

我错误地认为类型化常量存储在只读内存中,就像在其他语言中一样。事实并非如此。因此,您可以通过指针访问它来轻松更改此类型化常量的值。

PSize(@constant4).cx := 16;
PSize(@constant4).cy := 8;

将此代码添加到您的其中一个单元的初始化部分。您需要确保它运行得足够早,以便在执行任何依赖常量的代码之前影响更改。

我认为我的误解来自于字符串文字存储在只读内存中的知识。所以我假设类型化常量也是如此。我怀疑当添加可分配类型常量 "feature" 时,编译器开关只是让编译器拒绝写入类型常量,而不是将它们移动到只读内存。

请注意,我所说的只读内存在桌面编译器上是正确的。我不确定在移动编译器上是否如此。很可能是此代码因移动编译器上的运行时内存保护错误而失败。在这种情况下,您需要在写入之前临时更改内存保护。

我的建议:不要改常量,改方法。

检查使用常量的方法(过程或函数),然后"overload"使用新常量的方法。

如果它在 class 中,只需继承 class,并只修改方法,使用新名称,如过程 'aMethod_size2'。名称 size2 正在给出标志。

据我所知,这是通常的做法。