从函数指针获取函数名称?

时间:2012-01-13 07:31:29

标签: delphi function-pointers delphi-2007

我有一个指向这样的函数的指针。

TTestEvent = function(): Boolean;

procedure ExecuteTest(aTest: TTestEvent; aType: String);
begin
  if aTest then
    NotifyLog(aType + ' success')
  else
    TestError(aType + ' failed');
end;

// Call the test
procedure TestAll;
begin
  ExecuteTest(LoadParcels, 'LoadParcel');
end;

但是从functionpointer aTest中提取函数的名称会更好。

所以而不是

aType + ' success'

我想要像

这样的东西
ExtractName(aTest) + ' success'

这可以在Delphi 2007中完成吗?

3 个答案:

答案 0 :(得分:6)

如果你使用我们的一些开源类,你将能够找到任何符号的名称。

在构建可执行文件时,您必须通过在项目选项中设置“详细地图”来创建.map文件。

然后,您可以使用.map投放.exe,或将.map压缩为我们的专有.mab格式,该格式可以附加到.exe 。对于此任务,.mab格式比.zip或其他格式更有效:它比原始.map文件小10倍(即比JCLDebug或MaxExpect小得多)提供,并且比使用标准的“远程调试符号”嵌入项目选项小得多。

然后,您可以使用TSynMapFile类从.map文件中检索调试信息,或者嵌入.exe中的信息:

function ExtractName(aSymbolAddress: pointer): string;
var i: integer;
begin
  with TSynMapFile.Create do // no name supplied -> will read from .exe
  try
    i := FindSymbol(aSymbolAddress);
    if i>=0 then
      result := Symbols[i].Name else
      result := '';
  finally
    Free;
  end;
end;

它适用于函数名称,但也适用于任何其他符号,如方法或全局变量。

关于课程,请参阅this blog article。请注意,即使我们的mORMot框架或其日志记录功能使用它,您也不需要使用整个框架(仅SynCommons.pasSynLZ.pas单元)。请参阅“SQLite3 \ Samples \ 11 - 异常日志记录”子文件夹中的Map2Mab.dpr程序,将.map文件内容嵌入到.exe中。

答案 1 :(得分:4)

您无法使用内置功能执行此操作。要从地址获取函数名称,您需要知道可执行文件的映射。除非您采取措施添加它,否则这不是可执行文件的一部分。

JclDebug和madExcept等调试工具提供了您正在寻找的功能。

答案 2 :(得分:0)

您可以基于Dictionary

实施注册机制
  • 函数指针为Key
  • 函数名称为Value

ExtractName将成为字典的一种方法。

如果需要,不要忘记使其线程安全。