在关于关闭类帮助程序漏洞的辩论中,它允许轻松访问Delphi 10.1柏林中某个类的私有成员(字段和方法),但通常声称
但是,如果我运行这个简单的单元(一个带有一个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执行此操作。
答案 0 :(得分:3)
显而易见的结论是,虽然此类型是使用扩展RTTI编译的,但私有方法不包含RTTI。
答案 1 :(得分:1)
要使用RTTI访问严格私有/私有方法,请使用编译器指令{$RTTI}。
语法
$ RTTI指令的一般语法可以分为三个部分。 $ RTTI的基本形式如下:
{$ RTTI INHERIT | EXPLICIT [visibility-clause]}
<强>可视性子句:强>
方法|属性|字段(可见性 - 表达式)
<强>可视性表达强>
[vcPrivate],[vcProtected],[vcPublic],[vcPublished];
示例:
{$RTTI EXPLICIT METHODS([vcPublic, vcProtected, vcPrivate])}
设置public,protected和private方法的可见性
注意:此指令的范围是本地,而RTL/VCL/FMX
关闭了这些选项,这意味着可以访问 protected / private < / strong>无法使用RTTI方法。