如何从使用JclDebug的方法获取调用者TObject的地址

时间:2014-05-15 02:38:48

标签: delphi

我正在建立一个日志系统,所以我使用JclDebug单元使用ProcByLevel函数获取当前调用程序或函数的名称之类的堆栈信息。但现在我想获得调用者TObject的地址(Pointer)(适用时)。

我想编写一个函数,它传递调用方法的指针可以返回一个包含这种方法的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的地址,但是现在我是' m真的输了。

那么,我如何从使用JclDebug的方法中获取调用者TObject的地址?

1 个答案:

答案 0 :(得分:3)

通常,由于以下原因,此信息不可用:

  1. 您正在取消调用堆栈的函数调用可能不是一种方法。换句话说,可能没有Self
  2. 即使它是一种方法,此时也可能无法检索Self引用。请注意,Self只是一个参数,通常在eaxrax中传递。并且在代码运行时,该寄存器的内容可能已经改变。