1

I want to create a patch for the problem I reported as RSP-30853

In short, after loading my resouce DLL's I need to call sysutils.ResStringDeleteAllModules in order to flush the cached resource strings. Unfortunately this routine is NOT in the interface section, and modifying and recompiling sysutils.pas itself won't do it for me as I use runtime packages.

So I'm looking for a more-or-less hacky way to call this. I tried but did not find a route through TRTTIContext.

I also Tried this (with a fallback to LoadResStringFunc=nil for my specific problem) but to no avail:

procedure DropResStringCache;
begin
  var PModule:=LibModuleList;
  var P:=nil;
  while Assigned(PModule) do
  begin
    P:=GetProcAddress(PModule^.Instance,'ResStringDeleteAllModules');
    if Assigned(P) then
       break;
    PModule:=PModule.Next;
  end;
  if Assigned(P) then
    TProcedure(P)()
  else LoadResStringFunc:=nil;
end;
H.Hasenack
  • 1,094
  • 8
  • 27
  • Currently considering to copy all resourcestring cache code to a unit in my libs, and simply replace the system's LoadResSrtingFunc with the one in my new 'uResStringCache' unit. And in the process create a neater more object oriented class-based solution. – H.Hasenack Sep 07 '20 at 15:20
  • 1
    I've done this in the past by runtime disassembly to find the call instruction and therefor the address. You need to be able to locate a public function that calss the target function and disassemble that. – David Heffernan Sep 07 '20 at 15:41
  • @DavidHeffernan Yes I asummed something like that that already, or eg by using the map file. But in order to work around my actual problem of RSP-30853 I have created my own resourcestring cache which seems to do the job very well. Unfortunately my resourcestring specific solution is not an answer to the Q. The disassemble routine is IMO quite dangerous since you never know what EMB will think of next... – H.Hasenack Sep 07 '20 at 19:39
  • 1
    You have to test with every new version. But that's not too onerous. – David Heffernan Sep 07 '20 at 20:49

1 Answers1

0

If you have madExcept, you can use its GetMapFileAddress method to retrieve the address of the method like so:

var MethodAddr: Pointer := GetMapFileAddress(GetModuleName(HInstance), 'System.SysUtils', 'ResStringDeleteAllModules');

I believe the JCL also has support for runtime map file (or jdbg) parsing that would allow similar functionality.

OBones
  • 310
  • 2
  • 13