A bit of context... I need to write a fix for a bug in the VCL's TField.CopyData routine.
Not being a huge fan of recompiling the VCL, I usually opt for method hooks.
Usually, it's pretty straightforward, write the replacement method and hook it in place of the original one:
HookProc(@TMenu.ProcessMenuChar, @TPatchMenu.ProcessMenuChar, Backup);
But this time, the method is virtual and overloaded. I can't seem to find a reliable way to get the right method address.
If it wasn't overloaded, I could simply use @TField.CopyData
and it would work, but that isn't guaranteed to give the right address for an overloaded function.
If it wasn't virtual, I could extend the method described here and do the following
type
TCopyDataMethod = procedure(Source, Dest : TValueBuffer) of object;
procedure DoHook;
var vOldMethod : TCopyDataMethod;
begin
vOldMethod := TField(nil).CopyData;
HookProc(TMethod(vOldMethod).Code, @TSomeClass.NewMethod, Backup);
end;
But that gives an access violation (It is using the nil reference to lookup in the VMT for the right CopyData address).
I tried various syntax that all gave me "incompatible types" at compile time.
I did come up with a solution (posted as answer), but it is less than ideal.