Получить имя функции из указателя функции? - PullRequest
4 голосов
/ 13 января 2012

У меня есть указатель на такие функции.

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;

Но было бы еще лучше извлечь имя функции из указателя функции aTest.

Так что вместо

aType + ' success'

я хочу что-то вроде

ExtractName(aTest) + ' success'

Можно ли это сделать в Delphi 2007?

Ответы [ 3 ]

6 голосов
/ 13 января 2012

Если вы используете некоторые из наших классов с открытым исходным кодом, вы сможете найти имя любого символа.

Вам нужно будет создать файл .map при сборке исполняемого файла, установив «Подробную карту» в параметре ваших проектов.

Затем вы можете доставить .map с .exe или сжать .map в наш собственный .mab формат, который можно добавить к .exe. Формат .mab намного эффективнее, чем .zip или другой, для этой задачи: он примерно в 10 раз меньше исходного файла .map (то есть намного меньше, чем предлагают 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;

Это будет работать для имен функций, но также и для любых других символов, таких как методы или глобальные переменные.

См. статью этого блога о классе. И обратите внимание, что даже если он используется нашей платформой mORMot или ее функциями ведения журнала, вам просто не нужно использовать всю платформу (только SynCommons.pas и SynLZ.pas единиц ). См. Программу Map2Mab.dpr в подпапке «SQLite3 \ Samples \ 11 - Exception logging» для встраивания содержимого файла .map в .exe.

4 голосов
/ 13 января 2012

Вы не можете сделать это с помощью встроенных функций.Чтобы получить имя функции по адресу, вам необходимо знать карту исполняемого файла.Это не является частью исполняемого файла, если вы не предпримете шаги для его добавления.

Инструменты отладки, такие как JclDebug и madExcept, предлагают требуемую функциональность.

0 голосов
/ 13 января 2012

Вы можете реализовать механизм регистрации на основе Dictionary с

  • указателем функции как Key и
  • именем функции как Value.

ExtractName будет методом словаря.

Не забудьте сделать его потокобезопасным, если это необходимо.

...