Неверный тип: преобразование записи в tobject на 64-битной платформе

Он работает на 32-битной платформе. но не 64-битный вот пример

  TVerbInfo = packed record
    Verb: Smallint;
    Flags: Word;
  end;

var
  VerbInfo: TVerbInfo;
  strList : TStringList;
  verb : Smallint;
  flags : Word;
begin
  strList := TStringList.create();
  .....
  verbInfo.verb := verb;
  verbInfo.flags := flags;
  strList.addObject('verb1',TObject(VerbInfo));  //invalid typecast happened here
end;

Может кто-нибудь мне помочь? большое спасибо вам

3 ответа

Решение

Вы можете попробовать что-то вроде этого:

function MakeVerbInfoObject(const AVerbInfo: TVerbInfo): TObject;
begin
  Result := nil;
  Move(AVerbInfo, Result, SizeOf(AVerbInfo));
end;

strList.addObject('verb1', MakeVerbInfoObject(VerbInfo));

Ваш актерский состав TObject(VerbInfo) будет компилироваться при условии, что SizeOf(TObject) = SizeOf(TVerbInfo), Но TObject является указателем и поэтому его размер зависит от архитектуры. С другой стороны, SizeOf(TVerbInfo) не зависит от архитектуры. Следовательно, состав может работать только на одной архитектуре.

Использование приведений, подобных этому, - это то, как вы должны были делать вещи в префиниксах Delphi. Но в настоящее время вы должны использовать универсальные контейнеры.

Например, если у вас есть список и строки уникальны, вы можете использовать словарь:

TDictionary<string, TVerbInfo>

Если возможно наличие дублирующихся строк, вам потребуется новое объявление записи:

type
  TVerbInfo = record
    Name: string
    Verb: Integer;
    Flags: Word;
  end;

А затем сохранить список этих в

TList<TVerbInfo>

И последнее, что вы должны избегать использования упакованных записей. Это приводит к неправильному выравниванию структур данных, что, в свою очередь, приводит к снижению производительности.

Я думаю, что вы должны запустить это на разных платформах и сравнить результаты

ShowMessage( IntToStr( SizeOf( Integer ) ) );
ShowMessage( IntToStr( SizeOf( Pointer ) ) );
ShowMessage( IntToStr( SizeOf( TVerbInfo ) ) );
ShowMessage( IntToStr( SizeOf( TObject ) ) );

Я подозреваю, что вы не можете сделать hardcast, потому что размеры отличаются.

Вы можете попробовать использовать обходные пути, такие как

type TBoth = record
  case byte of
    0: ( rec: TVerbInfo);
    1: ( obj: TObject);
  end;

Вы также можете попробовать использовать TDictionary<String, TVerbInfo> тип вместо TStringList

Другие вопросы по тегам