简体   繁体   English

使用delphi枚举单元的全局方法

[英]Enumerate global methods of a unit using delphi

suppose i have a unit like this 假设我有一个这样的单位

unit sample;

interface

function Test1:Integer;
procedure Test2;

implementation

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

procedure Test2;
begin

end;

end.

Is possible enumerate all the procedures and functions of the unit sample in runtime? 是否可以在运行时枚举单元sample所有过程和功能?

No. RTTI is not generated for standalone methods. 否。不会为独立方法生成RTTI。 Hopefully this will be fixed in a later version, (they'd probably need a TRttiUnit type to do that,) but for now it's not available. 希望在以后的版本中可以解决此问题(它们可能需要使用TRttiUnit类型来实现),但目前尚不可用。

You could extract that information from some kind of debug info (TD32, Map file, Jdbg, etc.) using JCL and their great JclDebug.pas. 您可以使用JCL及其出色的JclDebug.pas从某种调试信息(TD32,Map文件,Jdbg等)中提取该信息。

Try this: 尝试这个:

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;

I don't think so. 我不这么认为。

That is a compile-time config, it's used so as the compiler knows which function name is being called or not. 这是一个编译时配置,用于编译器知道正在调用或不调用哪个函数名称的情况。 As far as I know, there is nothing at runtime which comes close to listing these functions. 据我所知,在运行时没有什么可以列出这些功能。

Delphi's excellent runtime features come from RTTI, you might want to see what it offers in relation to this. Delphi出色的运行时功能来自RTTI,您可能想看看它与此相关的功能。 But as I said, I don't think it's possible (know that I've delved in RTTI for quite some time...). 但是正如我所说,我认为这是不可能的(知道我已经在RTTI中研究了很长时间……)。

Edit: Oh and by the way, after compilation, functions lose their human-readable names (to addresses). 编辑:哦,顺便说一句,编译后,函数会丢失其人类可读的名称(至地址)。 There are some tables which pinpoint those names to addresses, most notably, RTTI and the Debug info. 有一些表格将这些名称精确定位到地址,最著名的是RTTI和调试信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM