mam tej klasy:błąd podczas próby uzyskania dostępu do klasy atrybutów
{$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;
Ja nazywam to w ten sposób: TReportItem.GetTableName<TReportItem>
; <>
może być dowolną klasą dziedziczącą TReportItem
.
Ale czasami, gdy zadzwonię: TReportItem.GetTableName
w poleceniu LRttiType.GetAttributes
Dostaję naruszenie dostępu, czasami nie, zależy od "kompilacji". Działa i przestaje działać jak magia. Nie wiem, co się dzieje. Ktoś może mi podpowiedzieć?
Problem dotyczy GetAttributes
, jeśli używam go, aby uzyskać atrybuty w polach, metodach itp. Daje mi to naruszenie zasad dostępu. Czy istnieje dyrektywa, którą muszę włączyć lub wyłączyć, aby z niej skorzystać?
Jeśli mogę skompilować za pomocą Shift + F9 , tym GetAttributes
dać mi AV, jeśli zmodyfikować dowolną linię w jednostce i skompilować za pomocą F9GetAttributes
prace.
to nie tylko w moim komputerze, pozostałe 8 programiści są z tym samym problemem. Delphi XE.
Błąd występuje w tym kodzie w 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 (i.e. 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;
można pokazać swoje wezwanie do 'TReportItem.GetTableName'. –
Kiedy otrzymujesz AV, jaką wartość ma 'LRttiType'? –
Przepraszam, czym jest AV? –