RTTI доступ к закрытым методам VCL, например TCustomForm.SetWindowState

В дебатах о закрытии лазейки вспомогательного класса, которая обеспечивала легкий доступ к закрытым членам (полям и методам) класса в Delphi 10.1 Berlin, часто утверждается, что

  • расширенный RTTI обеспечивает доступ к закрытым членам класса, который был скомпилирован с включенным (расширенным) RTTI, и
  • Все классы VCL/RTL/FMX имеют эту возможность.

Однако, если я запускаю этот простой модуль (простую форму с одним TListBox, больше ничего):

unit RttiAccessTest;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Rtti, Vcl.StdCtrls;

type
  TForm16 = class(TForm)
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form16: TForm16;

implementation

{$R *.dfm}

function GetMethodString(const MethodName: string): string;
var
  M: TRTTIMethod;
  I: Integer;
begin
  M := TRttiContext.Create.GetType(TCustomForm).GetMethod(MethodName);
  if Assigned(M) then
    Result := 'Method ' + MethodName + ': ''' + M.ToString + ';'''
  else
    Result := 'Method ' + MethodName + ' cannot be found';
end;

procedure TForm16.FormCreate(Sender: TObject);
begin
  Listbox1.Items.Add(GetMethodString('SetWindowState'));
  Listbox1.Items.Add(GetMethodString('ShowModal'));
end;

end.

Текст в списке:

Method SetWindowState cannot be found 
Method ShowModal: 'function ShowModal: Integer;'

Это означает, что я не могу получить доступ к этому приватному методу SetWindowState из TCustomForm, Это потому, что не все классы в RTL/VCL/FMX имеют расширенный RTTI или я что-то не так делаю?

Если я что-то делаю неправильно или что-то забываю, то что? Другими словами, что мне нужно сделать, чтобы получить доступ к RTTI, скажем, SetWindowState из TCustomForm? Я не могу получить этот доступ в Сиэтле или ранее.

Заметка

В любом случае я знаю, как получить доступ к методу, используя тот факт, что помощники класса могут все еще получить адрес закрытых методов, но это не мой вопрос. Я особенно спрашиваю о том, как сделать это с RTTI.

2 ответа

Решение

Чтобы получить доступ к строгим приватным / приватным методам с помощью RTTI, используйте директиву компилятора {$RTTI}.

Синтаксис

Общий синтаксис директивы $RTTI можно разделить на три части. Основная форма $RTTI выглядит следующим образом:

{$RTTI INHERIT | EXPLICIT [visibility-clause]}

видимость придаточного:

МЕТОДЫ | СВОЙСТВА | ПОЛЯ (выражение-видимость)

Видимость выражение:

[vcPrivate], [vcProtected], [vcPublic], [vcPublished];

Пример:

{$RTTI EXPLICIT METHODS([vcPublic, vcProtected, vcPrivate])}

Устанавливает видимость для открытых, защищенных и закрытых методов

Примечание: область действия является локальной для этой директивы и RTL/VCL/FMX отключите эти параметры, что означает, что доступ к защищенным / закрытым методам с RTTI невозможен.

Очевидный вывод заключается в том, что хотя этот тип компилируется с расширенным RTTI, этот RTTI не включен для частных методов.

Другие вопросы по тегам