Перечислите глобальные методы модуля, используя delphi - PullRequest
4 голосов
/ 10 октября 2010

предположим, у меня есть такой юнит

unit sample;

interface

function Test1:Integer;
procedure Test2;

implementation

function Test1:Integer;
begin
 result:=0;
end;

procedure Test2;
begin

end;

end.

Можно ли перечислить все процедуры и функции блока sample во время выполнения?

Ответы [ 3 ]

6 голосов
/ 10 октября 2010

Нет.RTTI не генерируется для автономных методов.Надеюсь, это будет исправлено в более поздней версии (для этого им, вероятно, потребуется тип TRttiUnit), но пока он недоступен.

1 голос
/ 31 июля 2011

Вы можете извлечь эту информацию из некоторой отладочной информации (TD32, файл карты, Jdbg и т. Д.), Используя JCL и их замечательный JclDebug.pas.

Попробуйте это:

uses
  JclDebug;

type
  TProc = record
    name: string;
    addr: Pointer;
  end;

  TProcArray = array of TProc;
  TMapLoader = class
  private
    FModule: Cardinal;
    FProcs: TProcArray;
    FMapFileName: string;
    FUnitName: string;
    procedure HandleOnPublicsByValue(Sender: TObject; const Address: TJclMapAddress; const Name: string);
  public
    constructor Create(const AFileName: string; AModule: Cardinal; const AUnitName: string);
    procedure Scan();
    property Procs: TProcArray read FProcs;
  end;

constructor TMapLoader.Create(const AFileName: string; AModule: Cardinal; const AUnitName: string);
begin
  inherited Create;
  FMapFileName := AFileName;
  FModule := AModule;
  FUnitName := AUnitName;
end;

procedure TMapLoader.HandleOnPublicsByValue(Sender: TObject; const Address: TJclMapAddress; const Name: string);
var
  l: Integer;
begin
  if Pos(FUnitName + '.', Name) = 1 then
  begin
    l := Length(FProcs);
    SetLength(FProcs, l + 1);
    FProcs[l].name := Name;
    FProcs[l].addr := Pointer(Address.Offset + FModule + $1000);
  end;
end;

procedure TMapLoader.Scan();
var
  parser: TJclMapParser;
begin
  parser := TJclMapParser.Create(FMapFileName, FModule);
  try
    parser.OnPublicsByValue := HandleOnPublicsByValue;
    parser.Parse;
  finally
    parser.Free;
  end;
end;
0 голосов
/ 10 октября 2010

Я так не думаю.

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

Превосходные функции Delphi во время выполнения получены от RTTI, вы можете захотеть посмотреть, что он предлагает в связи с этим.Но, как я уже сказал, я не думаю, что это возможно (знайте, что я уже давно изучал RTTI ...).

Редактировать: Да, кстати, после компиляции функции теряют своюудобочитаемые имена (по адресам).Есть несколько таблиц, которые указывают эти имена на адреса, в частности RTTI и информацию об отладке.

...