2012-02-29 9 views
6

que tienen esta clase:de error al intentar acceder a los atributos de clase

{$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; 

Me llaman de esta manera: TReportItem.GetTableName<TReportItem>; El <> puede ser cualquier clase que herede TReportItem.

Pero, a veces cuando llamo: TReportItem.GetTableName en el comando LRttiType.GetAttributes obtengo una infracción de acceso, a veces no, depende de la 'compilación'. Funciona y deja de funcionar como magia. No sé lo que está sucediendo. Alguien puede darme una pista?

El problema está en el GetAttributes, si lo uso para obtener atributos en campos, métodos, etc. Me da una infracción de acceso. ¿Hay alguna directiva que debo activar o desactivar para usarla?

Si puedo compilar usando Shift + F9, el GetAttributes dame AV, si modifico cualquier línea en la unidad y compilar usando F9GetAttributes obras.

No es solo en mi máquina, otros 8 programadores tienen el mismo problema. Delphi XE.

El error se produce en este código en 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

Puede mostrar su llamada a 'TReportItem.GetTableName'. –

+0

Cuando obtiene el AV, ¿qué valor tiene 'LRttiType'? –

+0

Disculpe, ¿Qué es AV? –

Respuesta

0

tuve el mismo problema exacto de horas de hoy, en la misma AV imp := PPPointer(p)^^ en Rtti.pas.

Descubrí que utilicé el mismo nombre para 2 atributos en 2 unidades no relacionadas en mi proyecto: después de renombrar uno de ellos, ¡no más AV!

+0

Tengo el mismo problema y no tengo atributos con el mismo nombre También he cambiado la unidad dentro del .dpr como @SaCi, pero el error persiste –

Cuestiones relacionadas