I use a third party library for which i need to change a constant. I would like to customize the library without overwriting the file. The pas file is a library file, not an inheritable class.
Currently i can achieve my goal by editing the file
unit libraryconstants;
interface
uses
System.Types;
const
constant1 = 'foo';
constant2 = 32;
constant3: Integer = 12;
constant4: TSize = (cx: 32; cy: 32);
Somehow I need to change constant4 like this:
constant4: TSize = (cx: 16; cy: 8);
I can edit libraryconstants.pas and save it, but as i update the library (because a new version is released) i will lose this change. Of course I can remind me to apply this change each time i update the library, but I'd like to avoid this if possible.
Since the constant is not a published property i do not know how to achieve the desired result. I'd like to interfere with the library code as less as possible.
I am looking for a Delphi language "trick" i do not know.
Thanks.
I was erroneously under the impression that typed constants are stored in read only memory, as they would be in other languages. That's not the case. So you can change the value of this typed constant quite easily by accessing it via a pointer.
PSize(@constant4).cx := 16;
PSize(@constant4).cy := 8;
Add this code to the initialization section of one of your units. You'll need to make sure that it runs early enough to effect the change before any code that depends on the constant is executed.
I think my misapprehension comes about through the knowledge that string literals are stored in read only memory. So I assumed that the same would be true for typed constants. I suspect that when the assignable typed constants "feature" was added, the compiler switch simply made the compiler reject writes to typed constants, rather than also moving them to read only memory.
Note that what I say about read only memory is true on the desktop compilers. I am not sure whether or not it is true on the mobile compilers. It may well be the case that this code fails with a runtime memory protection error on the mobile compilers. In which case you would need temporarily to alter the memory protection before writing to it.
Make a new 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.
then list this unit in the USES statement AFTER the libraryconstants unit in your application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With