2010-10-09 2 views
4

Supposons que j'ai une unité comme celui-ciÉnumérer méthodes globales d'une unité à l'aide delphi

unit sample; 

interface 

function Test1:Integer; 
procedure Test2; 

implementation 

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

procedure Test2; 
begin 

end; 

end. 

est possible d'énumérer toutes les procédures et fonctions de l'unité sample en exécution?

+0

@Kirk, ce qui est réellement votre objectif? – Vantomex

Répondre

6

Non RTTI n'est pas généré pour les méthodes autonomes. Espérons que cela sera corrigé dans une version ultérieure, (ils auraient probablement besoin d'un type TRttiUnit pour le faire, mais pour l'instant ce n'est pas disponible.

0

Je ne pense pas.

Il s'agit d'une configuration à la compilation, elle est utilisée pour que le compilateur sache quel nom de fonction est appelé ou non. Pour autant que je sache, il n'y a rien à l'exécution qui se rapproche de la liste de ces fonctions.

Les excellentes fonctions d'exécution de Delphi viennent de RTTI, vous voudrez peut-être voir ce qu'il offre par rapport à cela. Mais comme je l'ai dit, je ne pense pas que ce soit possible (sachez que je me suis plongé dans RTTI depuis un certain temps ...).

Editer: Oh, et en passant, après la compilation, les fonctions perdent leurs noms lisibles par l'homme (aux adresses). Il y a quelques tables qui localisent ces noms aux adresses, en particulier, RTTI et les informations de débogage.

1

Vous pouvez extraire cette information à partir d'un type d'information de débogage (TD32, fichier Map, Jdbg, etc.) en utilisant JCL et leur super JclDebug.pas.

Essayez ceci:

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; 
Questions connexes