Неверный тип: преобразование записи в 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