I'm building a logging system, So I'm using the JclDebug unit to obtain stack info like the name of the current caller procedure or function using the ProcByLevel
function. But now I like to obtain the address (Pointer) of the caller TObject (when applies).
I want to write a function which passing the pointer of the caller method can return a instance to TObject which contains such method. like so
function GetCallerObject(CallerMethodAddress: Pointer) : TObject;
begin
//here I'm lost
end;
See this code
{$APPTYPE CONSOLE}
{$R *.res}
uses
Windows,
JCLDebug,
SysUtils;
Type
TFooClass=class
public
procedure methodCaller;
end;
procedure Show;
var
s : string;
i : Integer;
LocationInfo : TJclLocationInfo;
begin
Writeln('show');
//values for the levels are harcoded for this sample
LocationInfo:=GetLocationInfo(Caller(1));
Writeln(ProcByLevel(1)+' '+Format('Caller %s %p',[LocationInfo.ProcedureName, LocationInfo.Address ]));
//here I want get the address of TFooClass class which calls this method (Show)
Writeln(GetCallerObject(LocationInfo.Address).ClassName); //this must return TFooClass
end;
procedure TFooClass.MethodCaller;
begin
Writeln(Format('Self %p',[Pointer(Self)]));
Writeln(Format('Real Caller Address %p',[Caller(0)]));
show;
end;
var
M : TFooClass;
begin
try
M:=TFooClass.Create;
try
M.methodCaller;
finally
M.Free;
end;
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
With the above code I'm getting some address, but none match with the address of the caller object (Self of TFooClass), I really read the full code of the JclDebug unit , but i not found any reference to the caller object, only can be retrieved the stack names which includes the class name what i'm looking for, So that make think which must be possible return the address of the caller TObject as well, but now I'm really lost.
So, how I can get the address of the caller TObject from a method using JclDebug?