I get RTTIMethod.Visibility = mvPublic for a private record method. — Bug?
我使用 Delphi 10.2 获得了一个(严格的)私有记录方法的 RTTIMethod.Visibility = mvPublic。这是一个错误吗?
2017 年 7 月 12 日更新:已创建问题:RSP-18587。
程序输出显示记录和类的所有实例成员类型和可见性;从 RTTI 返回的可见性;在 TSomeRec 中查找 PrivateProcedure:
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 |
Types:
Unit1.TSomeRec Fields: PrivateField Visibility: mvPrivate PublicField Visibility: mvPublic Properties: Methods: PrivateProcedure Visibility: mvPublic PrivateFunction Visibility: mvPublic PublicProcedure Visibility: mvPublic PublicFunction Visibility: mvPublic Unit1.TSomeClass Fields: PrivateField Visibility: mvPrivate ProtectedField Visibility: mvProtected PublicField Visibility: mvPublic Properties: PrivateProperty Visibility: mvPrivate ProtectedProperty Visibility: mvProtected PublicProperty Visibility: mvPublic PublishedProperty Visibility: mvPublished Methods: PrivateProcedure Visibility: mvPrivate PrivateFunction Visibility: mvPrivate ProtectedProcedure Visibility: mvProtected ProtectedFunction Visibility: mvProtected PublicProcedure Visibility: mvPublic PublicFunction Visibility: mvPublic PublishedProcedure Visibility: mvPublished PublishedFunction Visibility: mvPublished |
Unit1.pas:
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 |
unit Unit1;
interface {$RTTI explicit {$Region ‘TSomeRec’} type public {$EndRegion} type strict protected public published {$EndRegion} implementation {$Region ‘TSomeRec’} { TSomeRec } function TSomeRec.PrivateFunction: Boolean; procedure TSomeRec.PrivateProcedure; function TSomeRec.PublicFunction: Boolean; procedure TSomeRec.PublicProcedure; {$EndRegion} { TSomeClass } function TSomeClass.PrivateFunction: Boolean; procedure TSomeClass.PrivateProcedure; function TSomeClass.ProtectedFunction: Boolean; procedure TSomeClass.ProtectedProcedure; function TSomeClass.PublicFunction: Boolean; procedure TSomeClass.PublicProcedure; function TSomeClass.PublishedFunction: Boolean; procedure TSomeClass.PublishedProcedure; {$EndRegion} end. |
Project1.dpr:
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 |
program Project1;
{$AppType Console} {$R *.res} uses {$Region ‘IWriter, TWriter’} type TWriter = class (TInterfacedObject, IWriter) strict protected public { TWriter } procedure TWriter.BeginSection(const Value: String); procedure TWriter.EndSection; procedure TWriter.WriteLn(const Value: String); procedure TWriter.WriteMemberSection(const Value: TRTTIMember); {$EndRegion} {$Region ‘…’} procedure Run; {$EndRegion} begin |
- 是的,这看起来像一个错误。
- 我在 Delphi 10.2 和 Delphi XE3 中重复了你的结果。
- @DaveOlson:我只尝试过 XE6 和 Tokyo,也得到了相同的结果。这似乎是一个比较古老的错误。
错误是在 TRttiRecordMethod 中没有覆盖 GetVisibility。我看了一点代码,关于可见性的信息实际上在 Flag 字段中。
与其他 GetVisibility 覆盖(例如 TRttiRecordField)类似,它需要实现。我将此报告为 RSP-18588。
我写了一个小补丁,如果你真的需要修复这个问题(仅限 Windows)。
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 |
unit PatchRecordMethodGetVisibility;
interface implementation uses type procedure TRec.Method; function GetVirtualMethod(AClass: TClass; const Index: Integer): Pointer; procedure RedirectFunction(OrgProc, NewProc: Pointer); type procedure PatchIt; { TRttiRecordMethodFix } function TRttiRecordMethodFix.GetVisibility: TMemberVisibility; function GetBitField(Value, Shift, Bits: Integer): Integer; const initialization end. |
- 虽然代码尚未投入生产,但该补丁可以构建正确的行为并继续在 Windows 下进行开发和测试。一旦要构建非 Windows 变体,我将重新审视这个问题,我希望到那时能找到一个固定的 RTL。非常感谢 Stefan Glienke、@RudyVelthuis 和 @DaveOlson!
来源:https://www.codenong.com/45040739/