我有一个指向这样的函数的指针。
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中完成吗?
答案 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.pas
和SynLZ.pas
单元)。请参阅“SQLite3 \ Samples \ 11 - 异常日志记录”子文件夹中的Map2Mab.dpr程序,将.map文件内容嵌入到.exe中。
答案 1 :(得分:4)
您无法使用内置功能执行此操作。要从地址获取函数名称,您需要知道可执行文件的映射。除非您采取措施添加它,否则这不是可执行文件的一部分。
JclDebug和madExcept等调试工具提供了您正在寻找的功能。
答案 2 :(得分:0)
您可以基于Dictionary
和
Key
和Value
。 ExtractName
将成为字典的一种方法。
如果需要,不要忘记使其线程安全。