I have this class:
{$RTTI EXPLICIT FIELDS([vcProtected]) PROPERTIES([vcProtected])} const PP_VEHICLE_FIELD = 'VEICULO_ID'; PP_DRIVER_FIELD = 'MOTORISTA_ID'; PP_TRIP_FIELD = 'VIAGEM_ID'; PP_DATE = 'DATA'; type [TAttrDBTable('NONE')] TReportItem = class(TObject) protected [TAttrDBField(PP_VEHICLE_FIELD)] FVeiculoId: integer; [TAttrDBField(PP_DRIVER_FIELD)] FMotoristaId: integer; [TAttrDBField(PP_TRIP_FIELD)] FViagemId: integer; [TAttrDBField(PP_DATE)] FDataRelatorio: TDate; published class function GetTableName<T: class, constructor>: string; end. class function TReportItem.GetTableName<T>: string; var LRttiContext: TRttiContext; LRttiType: TRttiType; LCustomAttribute: TCustomAttribute; LType: T; begin LType := T.Create; try LRttiContext := TRttiContext.Create; LRttiType := LRttiContext.GetType(LType.ClassType); for LCustomAttribute in LRttiType.GetAttributes do if LCustomAttribute is TAttrDBTable then begin Result := TAttrDBTable(LCustomAttribute).TableName; Break; end; finally LType.Free; end; end;
I call it this way: TReportItem.GetTableName<TReportItem>
; <>
can be any class that inherits TReportItem
.
But sometimes, when I call: TReportItem.GetTableName
on the LRttiType.GetAttributes
, I get an access violation, sometimes not, it depends on the โcompilationโ. It works and stops working like magic. I do not know what's going on. Can anyone give me a hint?
The problem is GetAttributes
if I use this to get attributes in properties, methods, etc. This gives me an access violation. Is there some kind of directive that I have to turn on or off in order to use it?
If I compile with Shift + F9 , GetAttributes
will give me AV if I change any line in the module and compile with F9 GetAttributes
.
This is not only in my machine, the other 8 programmers have the same problem. Delphi XE.
An error occurs in this code in rtti.pas:
function FindCtor(AttrType: TRttiInstanceType; CtorAddr: Pointer): TRttiMethod; type PPPointer = ^PPointer; var p: PByte; imp: Pointer; begin for Result in AttrType.GetMethods do if Result.CodeAddress = CtorAddr then Exit; // expect a package (ie DLL) import p := CtorAddr; Assert(p^ = $FF); // $FF $25 => indirect jump m32 Inc(p); Assert(p^ = $25); Inc(p); imp := PPPointer(p)^^; //ERROR HAPPENS HERE for Result in attrType.GetMethods do if Result.CodeAddress = imp then Exit; Result := nil; end;
source share