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

发布于 2024-09-26 23:10:17 字数 260 浏览 1 评论 0原文

假设我有一个像这样的单元

unit sample;

interface

function Test1:Integer;
procedure Test2;

implementation

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

procedure Test2;
begin

end;

end.

是否可以在运行时枚举单元sample的所有过程和函数?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

请远离我 2024-10-03 23:10:17

不会。RTTI 不是为独立方法生成的。希望这将在以后的版本中得到修复(他们可能需要 TRttiUnit 类型来做到这一点),但目前它不可用。

No. RTTI is not generated for standalone methods. 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.

谁把谁当真 2024-10-03 23:10:17

您可以使用 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;

You could extract that information from some kind of debug info (TD32, Map file, Jdbg, etc.) using JCL and their great JclDebug.pas.

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;
海未深 2024-10-03 23:10:17

我不这么认为。

这是一个编译时配置,使用它是为了让编译器知道哪个函数名称正在被调用或没有被调用。据我所知,在运行时没有什么比列出这些函数更接近的了。

Delphi 优秀的运行时特性来自 RTTI,您可能想看看它提供了与此相关的功能。但正如我所说,我认为这是不可能的(要知道我已经研究 RTTI 相当长一段时间了......)。

编辑:哦,顺便说一句,编译后,函数会丢失其人类可读的名称(地址)。有一些表可以将这些名称精确定位到地址,最值得注意的是 RTTI 和调试信息。

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. But as I said, I don't think it's possible (know that I've delved in RTTI for quite some time...).

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文