我使用第三方库,我需要更改常量。我想自定义库而不覆盖文件。 pas文件是库文件,而不是可继承的类。
目前我可以通过编辑文件来实现我的目标
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语言"技巧"我不知道。
感谢。
答案 0 :(得分:3)
我错误地认为输入的常量存储在只读存储器中,就像在其他语言中一样。事实并非如此。因此,您可以通过指针访问它来非常轻松地更改此类型常量的值。
PSize(@constant4).cx := 16;
PSize(@constant4).cy := 8;
将此代码添加到您的某个单元的初始化部分。在执行任何依赖于常量的代码之前,您需要确保它足够早地运行以实现更改。
我认为我的误解来自于字符串文字存储在只读内存中的知识。所以我假设类型常量也是如此。我怀疑当添加可分配的类型常量“feature”时,编译器开关只是让编译器拒绝写入类型常量,而不是将它们移动到只读内存。
请注意,我对只读内存的说法在桌面编译器上是正确的。我不确定它是否适用于移动编译器。很可能是这个代码在移动编译器上因运行时内存保护错误而失败。在这种情况下,您需要在写入之前暂时更改内存保护。
答案 1 :(得分:1)
制作一个新单位:
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语句中列出此单元。
答案 2 :(得分:0)
我的建议:不要改变常数,改变方法。
使用常量检查什么方法(过程或函数),然后使用新常量“重载”该方法。
如果它在一个类中,只需继承该类,并仅使用新名称修改该方法,如过程'aMethod_size2'。名字大小2给出了关于它的标志。
这是我所知道的通常做法。
答案 3 :(得分:-1)
在项目设置中( CTRL + SHIFT + F11 ):
Delphi compiler \ Compiling \ Syntax options
将“可分配的类型常量”的值更改为True。 然后,您可以将类型常量修改为常规变量:
constant4.cx := 16;
constant4.cy := 8;