如何在不改变库文件的情况下修改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 正在给出标志。
据我所知,这是通常的做法。
我使用第三方库,我需要为其更改常量。我想自定义库而不覆盖文件。 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 正在给出标志。
据我所知,这是通常的做法。