如何在 Delphi 中获取当前方法名?

dzjeubhm  于 2023-01-20  发布在  其他
关注(0)|答案(3)|浏览(253)

有没有办法知道我当前使用的方法的名称?
因此:

procedure TMyObject.SomeMethod();
begin
  Writeln('my name is: ' + <hocus pocus>); 
end;

将产生以下输出:
my name is: SomeMethod

qyuhtwio

qyuhtwio1#

JCL是自由的,并且有相关的函数。这取决于堆栈跟踪的效果如何,以及存在多少调试信息。
JclDebug.pas

function FileByLevel(const Level: Integer = 0): string;
function ModuleByLevel(const Level: Integer = 0): string;
function ProcByLevel(const Level: Integer = 0): string;
function LineByLevel(const Level: Integer = 0): Integer;
smdncfj3

smdncfj32#

另请参见our TSynMapFile class
它能够加载.map文件,并将其压缩为优化的二进制格式。它将比.map本身小得多(例如900 KB .map-〉70 KB .mab)。此.mab可以轻松嵌入到exe中。因此,它比JCL或MadExcept使用的格式小,并且也小于由Delphi在编译时嵌入的信息。
您将按如下方式使用它:

Map := TSynMapFile.Create; // or specify an exe name
try
  i := Map.FindSymbol(SymbolAddr);
  if i>=0 then 
    writeln(Map.Symbols[i].Name);
  // or for your point:
  writeln(Map.FindLocation(Addr)); // e.g. 'SynSelfTests.TestPeopleProc (784)'
finally
  Map.Free;
end;

例如,下面是如何从我们的日志记录类中使用它。

procedure TSynLog.Log(Level: TSynLogInfo);
var aCaller: PtrUInt;
begin
  if (self<>nil) and (Level in fFamily.fLevel) then begin
    LogHeaderLock(Level);
    asm
      mov eax,[ebp+4]  // retrieve caller EIP from push ebp; mov ebp,esp
      sub eax,5        // ignore call TSynLog.Enter op codes
      mov aCaller,eax
    end;
    TSynMapFile.Log(fWriter,aCaller); // here it will call TSynMapFile for the current exe
    LogTrailerUnLock(Level);
  end;
end;

此方法能够检索调用者的地址,并记录其单元名、方法名和行号。
注/编辑:mORMot日志单元的源代码为SynLog.pas,更新后的文档可以在这个URI上找到。

yruzcnhs

yruzcnhs3#

如果您有EurekaLog:

uses
  EDebugInfo;

procedure TMyObject.SomeMethod();
begin
  Writeln('my name is: ' + __FUNCTION__); 
end;

还有__FILE____MODULE____UNIT____LINE__,以及一个通用的GetLocationInfoStr函数。
然而:
1.只有在使用一些调试信息(以及corresponding debug info provider is enabled)进行编译时,它才能工作:

  • EurekaLog有自己的调试信息格式,可以选择压缩(实际上不推荐压缩,因为这会花费更多的内存和CPU)。
  • 它还支持JCL/JEDI、Synopse/MAB以及. map、. tds/TD32、. dbg和. pdb。

1.它不是一个常量。名字将被动态查找,所以它有一些运行时间开销。

相关问题