我有这个课:

{$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位程序员遇到了同样的问题。德尔福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;

最佳答案

我今天有几个小时完全相同的问题,Rtti.pas中imp := PPPointer(p)^^上的AV也相同。

我发现我在项目的2个无关单元中为2个属性使用了相同的名称:重命名其中之一后,不再需要AV!

08-19 15:58