Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 747
LaBracca Avatar asked Jan 01 '26 13:01

LaBracca


2 Answers

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.

like image 173
David Heffernan Avatar answered Jan 05 '26 14:01

David Heffernan


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.

like image 45
HeartWare Avatar answered Jan 05 '26 14:01

HeartWare



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!