Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как получить имена методов класса в Делфи 7 ? / 5 сообщений из 5, страница 1 из 1
02.06.2020, 19:13
    #39965425
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить имена методов класса в Делфи 7 ?
Всем привет!
На руках имеется исходник (D7) для получения имён методов, их параметров,
адресов и их смещений при помощи директивы {$METHODINFO ON}.
НО, только для текущего класса. Как получить имена методов, используя
RTTI из D2010 мне известно, но как это сделать в D7 ?
Ведь среда же их как-то узнаёт при вводе в редакторе объекта и разделительной
точки. Так же имеется небольшой модуль-набросок для получения
имён методов и их параметров, но компилятор ругается на классы-helpers
в разделе interface, так как в Делфи 7 нет никаких helper. У кого версия выше 2010
пожалуйста компильните этот модуль,- выдаёт ли он имя метода?
И я подозреваю, что разгадка кроется в ObjAuto.pas
Есть ли какая альтернатива этим Хелперам?
Выкладываю модуль:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
unit DetailedRTTI;

interface

uses
  TypInfo, ObjAuto;


type

  TParamInfoHelper = record helper for TParamInfo
  public
   function AsString: string;
   function NextParam: PParamInfo;
  end;

  TReturnInfoHelper = record helper for TReturnInfo
  public
   function AsString: string;
  end;

  TMethodInfoHeaderHelper = record helper for TMethodInfoHeader
  private
    function GetReturnInfo: PReturnInfo;
  public
    property ReturnInfo: PReturnInfo read GetReturnInfo;
  end;

  TObjectHelper = class helper for TObject
  public
    function RTTIMethodsAsString: string;
  end;

  function DescriptionOfMethod( Obj: TObject; MethodName: string ): string;

implementation

uses
  SysUtils;

const
  SHORT_LEN = sizeof(ShortString) - 1;

function DescriptionOfMethod( Obj: TObject; MethodName: string ): string;
var
  header: PMethodInfoHeader;
  headerEnd: Pointer;
  Params, Param: PParamInfo;
  returnInfo: PReturnInfo;
begin
  header := ObjAuto.GetMethodInfo( Obj, MethodName );
  // Check the length is greater than just that of the name
  if Header.Len <= SizeOf(TMethodInfoHeader) - SHORT_LEN + Length(Header.Name) then
  begin
    Result := 'No rich RTTI';
    exit;
  end;

  headerEnd := Pointer(Integer(header) + header^.Len);
  // Get a pointer to the param info
  Params := PParamInfo(Integer(header) + SizeOf(header^) - SHORT_LEN + SizeOf(TReturnInfo) + Length(header^.Name));
  // Loop over the parameters
  Param := Params;
  Result := '';
  while Integer(Param) < Integer(headerEnd) do
  begin
    Result := Result + Param.AsString + '; ';
    // Find next param
    Param := Param.NextParam;
  end;
  Delete( Result, Length(Result)-1,2 );

  // Now the return
  returnInfo := header.ReturnInfo;
  if assigned( returnInfo.ReturnType ) then
    Result := Format( 'function %s( %s ): %s', [ MethodName, Result, returnInfo.AsString ] )
  else
    Result := Format( 'procedure %s( %s )%s', [ MethodName, Result, returnInfo.AsString ] );
end;

{ TParamInfoHelper }

function TParamInfoHelper.AsString: string;
begin
  Result := '';
  if pfResult in Flags then exit;         // Seems to be extra info about the return function, not sure what it means
  Result := Name + ': ' + ParamType^.Name;
  if pfVar in self.Flags then             // Should really handle the other flags here
    Result := 'var ' + Result;
end;

function TParamInfoHelper.NextParam: PParamInfo;
begin
  Result := PParamInfo(Integer(@self) + SizeOf(self) - SHORT_LEN + Length(Name));
end;

{ TMethodInfoHeaderHelper }

function TMethodInfoHeaderHelper.GetReturnInfo: PReturnInfo;
begin
  Result := PReturnInfo(Integer(@self) + SizeOf(TMethodInfoHeader) - SHORT_LEN + Length(Name));
end;

{ TReturnInfoHelper }

function TReturnInfoHelper.AsString: string;
var
  c: string;
begin
  Assert( Version = 1, 'Version of ReturnInfo incorrect' );
  if assigned( ReturnType ) then
    Result := ReturnType^.Name;
  Result := Result + ';';
  case CallingConvention of
    ccRegister: ;// Default
    ccCdecl: c := 'cdecl';
    ccPascal: c := 'pascal';
    ccStdCall: c := 'stdcall';
    ccSafeCall: c := 'safecall';
  end;
  if c <> '' then Result := Result + ' ' + c + ';';
end;

{ TObjectHelper }

function TObjectHelper.RTTIMethodsAsString: string;
var
  MethodInfo: Pointer;
  Count: Integer;
  method: PMethodInfoHeader;
  i: Integer;
begin
    MethodInfo := PPointer(Integer(PPointer(self)^) + vmtMethodTable)^;
    if MethodInfo <> nil then
    begin
      // Scan method and get string about each
      Count := PWord(MethodInfo)^;
      Inc(Integer(MethodInfo), 2);
      method := MethodInfo;
      for i := 0 to Count - 1 do
      begin
        Result := Result + DescriptionOfMethod(self, method.Name) + sLineBreak;
        Inc(Integer(method), PMethodInfoHeader(method)^.Len); // Get next method
      end;
    end;
end;

end.


...
А вот и архив с рабочим исходником под Д7 для получения имён
методов, их параметров, адресов и смещений, но для текущего класса!
...
Рейтинг: 0 / 0
02.06.2020, 19:31
    #39965428
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить имена методов класса в Делфи 7 ?
Вот результат, но только для текущего класса.
...
Рейтинг: 0 / 0
02.06.2020, 19:42
    #39965430
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить имена методов класса в Делфи 7 ?
Linux_64
Есть ли какая альтернатива этим Хелперам?

Хелперы это просто функции принимающие в первом параметре переменную того типа, для которого написан этот хелпер. Например:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
  TReturnInfoHelper = record helper for TReturnInfo
  public
   function AsString: string;
  end;

{ TReturnInfoHelper }

function TReturnInfoHelper.AsString: string;
var
  c: string;
begin
  Assert( Version = 1, 'Version of ReturnInfo incorrect' );
  if assigned( ReturnType ) then
    Result := ReturnType^.Name;
  Result := Result + ';';
  case CallingConvention of
    ccRegister: ;// Default
    ccCdecl: c := 'cdecl';
    ccPascal: c := 'pascal';
    ccStdCall: c := 'stdcall';
    ccSafeCall: c := 'safecall';
  end;
  if c <> '' then Result := Result + ' ' + c + ';';
end;


Можно переписать так (подразумеваемый Self заменяется первым параметром):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
function ReturnInfoToString(const AInfo : TReturnInfo) : string;
var
  c: string;
begin
  Assert( AInfo.Version = 1, 'Version of ReturnInfo incorrect' );
  if assigned( AInfo.ReturnType ) then
    Result := AInfo.ReturnType^.Name;
  Result := Result + ';';
  case AInfo.CallingConvention of
    ccRegister: ;// Default
    ccCdecl: c := 'cdecl';
    ccPascal: c := 'pascal';
    ccStdCall: c := 'stdcall';
    ccSafeCall: c := 'safecall';
  end;
  if c <> '' then Result := Result + ' ' + c + ';';
end;


Соответственно, вызовы хелпера заменяются аналогично:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
var
 i : ReturnInfo;

...

// i.AsString заменяется на
ReturnInfoToString(i);
...
Рейтинг: 0 / 0
02.06.2020, 19:54
    #39965433
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить имена методов класса в Делфи 7 ?
Kazantsev Alexey,
Кажись понял. Буду пробовать. Спасибо!
...
Рейтинг: 0 / 0
03.06.2020, 12:00
    #39965596
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как получить имена методов класса в Делфи 7 ?
Kazantsev Alexey
Хелперы это просто функции принимающие в первом параметре переменную того типа, для которого написан этот хелпер
И имеющие доступ к protected секции.

Хотя т.к. в Д7 нет strict protected, то эту проблему можно обойти хак-классом
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как получить имена методов класса в Делфи 7 ? / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]