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

问题描述:

有什么方法可以知道我目前使用的方法的名称吗?如何在Delphi 7中获取当前方法的名称?

这样:

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

会产生这样的输出:

my name is: SomeMethod

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; 
+14

我会添加这个简单不能没有某种调试信息。 – 2009-08-19 17:42:53

our TSynMapFile class见。

它能够加载.map文件,并将其压缩为优化的二进制格式。它将比.map本身小得多(例如900KB .map-> 70KB .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; 

此方法能够检索调用者的地址,并记录其单元名称,方法名称和行号。

+0

你可以使用它来从一个普通的调试版本(或带有外部映射的版本?)中记录调用堆栈,而无需添加例如Jedi调试代码?在某些特定情况下,拥有可以记录和报告从何处调用的代码可能非常有用。 – 2014-01-28 19:27:41

+0

@DavidM是的,你可以做到这一点。如果没有附加.map/.mab,它会记录十六进制地址。然后我们的LogView工具能够从与.exe匹配的现有.map文件中检索源代码行。但是,当然,由于我们的.mab格式非常小,我没有看到任何理由不在编译时将其嵌入到.exe中。 – 2015-05-25 09:21:12

+0

@ArnaudBouchez你能告诉如何在编译时将它嵌入到.exe中吗? – SOUser 2015-10-18 02:18:11