我正在构建一个日志系统,因此我使用 JclDebug 单元来获取堆栈信息,例如使用 ProcByLevel
函数的当前调用程序或函数的名称。但现在我想获取调用者 TObject 的地址(指针)(适用时)。
我想编写一个函数,传递调用者方法的指针可以将实例返回到包含此类方法的 TObject。像这样
function GetCallerObject(CallerMethodAddress: Pointer) : TObject;
begin
//here I'm lost
end;
查看此代码
{$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.
通过上面的代码,我得到了一些地址,但没有一个与调用者对象的地址(TFooClass的Self)匹配,我确实阅读了JclDebug单元的完整代码,但我没有找到任何对调用者的引用对象,只能检索堆栈名称,其中包括我正在寻找的类名,因此使人认为这也必须可能返回调用者 TObject 的地址,但现在我真的迷失了。
那么,如何使用 JclDebug 从方法中获取调用者 TObject 的地址?
最佳答案
一般来说,由于以下原因,此信息不可用:
- 您从调用堆栈中选取的函数调用可能不是方法。换句话说,可能不存在
self
。 - 即使它是一个方法,此时也可能无法检索
Self
引用。请记住,Self
只是一个参数,通常以eax
或rax
形式传递。当您的代码运行时,该寄存器的内容很可能已经改变。
关于delphi - 如何使用 JclDebug 从方法中获取调用者 TObject 的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23668356/