Ошибка при попытке доступа к атрибутам класса - PullRequest
6 голосов
/ 29 февраля 2012

У меня есть этот класс:

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

Я называю это так: TReportItem.GetTableName<TReportItem>;<> может быть любым классом, который наследует TReportItem.

Но иногда, когда я вызываю: TReportItem.GetTableName в команде LRttiType.GetAttributes Я получаю нарушение прав доступа, иногда нет, зависит от компиляции '».Это работает и перестает работать как магия.Я не знаю, что происходит.Кто-то может дать мне подсказку?

Проблема в GetAttributes, если я использую это для получения атрибутов в полях, методах и т. Д. Это дает мне нарушение прав доступа.Есть ли какая-то директива, которую я должен включить или выключить, чтобы использовать ее?

Если я скомпилирую, используя Shift + F9 , GetAttributes даст мне AV, если я изменю любую строку вмодуль и компиляция с использованием F9 GetAttributes работает.

Это не только на моей машине, остальные 8 программистов имеют ту же проблему.Delphi XE.

Ошибка в этом коде в 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;

1 Ответ

0 голосов
/ 15 января 2013

У меня была та же самая проблема с часами сегодня, тот же AV на imp := PPPointer(p)^^ в Rtti.pas.

Я обнаружил, что я использовал одно и то же имя для 2 атрибутов в 2 несвязанных единицах в моем проекте: после того, как я переименовал один из них, больше нет AV!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...