2012-02-29 28 views
6

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; 
+0

można pokazać swoje wezwanie do 'TReportItem.GetTableName'. –

+0

Kiedy otrzymujesz AV, jaką wartość ma 'LRttiType'? –

+0

Przepraszam, czym jest AV? –

Odpowiedz

0

miałem identyczny problem na wiele godzin dzisiaj, sam AV na imp := PPPointer(p)^^ w Rtti.pas.

odkryłem, że użyłem tej samej nazwy dla 2 atrybutów w 2 niezależnych jednostek w moim projekcie: po I przemianowany na jedną z nich, nie więcej AV!

+0

Mam ten sam problem i nie mam atrybutów o tej samej nazwie. Zmieniłem także jednostkę wewnątrz .dpr jako @SaCi, ale błąd nie zniknął –

Powiązane problemy