假设我有这样的单位
unit sample;
interface
function Test1:Integer;
procedure Test2;
implementation
function Test1:Integer;
begin
result:=0;
end;
procedure Test2;
begin
end;
end.
是否可以在运行时枚举单元的所有程序和功能sample
?
假设我有这样的单位
unit sample;
interface
function Test1:Integer;
procedure Test2;
implementation
function Test1:Integer;
begin
result:=0;
end;
procedure Test2;
begin
end;
end.
是否可以在运行时枚举单元的所有程序和功能sample
?
不,不会为独立方法生成 RTTI。希望这将在以后的版本中得到修复,(他们可能需要一个 TRttiUnit 类型来做到这一点,)但现在它不可用。
您可以使用JCL及其出色的 JclDebug.pas从某种调试信息(TD32、映射文件、Jdbg 等)中提取该信息。
尝试这个:
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;
我不这么认为。
这是一个编译时配置,它用于编译器知道正在调用哪个函数名。据我所知,在运行时没有任何东西可以接近列出这些函数。
Delphi 出色的运行时特性来自 RTTI,您可能想看看它提供的与此相关的功能。但正如我所说,我认为这是不可能的(知道我已经研究 RTTI 很长一段时间了......)。
编辑:哦,顺便说一句,在编译之后,函数会丢失它们人类可读的名称(地址)。有一些表格将这些名称精确定位到地址,最值得注意的是 RTTI 和调试信息。