无效的类型转换:在64位平台上将记录转换为tobject

时间:2013-12-19 11:11:44

标签: delphi casting 64-bit record tobject

它适用于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 个答案:

答案 0 :(得分:3)

您可以尝试这样的事情:

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

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

答案 1 :(得分:3)

如果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>

最后一点是你应该避免使用打包记录。这会导致数据结构错位,从而导致性能下降。

答案 2 :(得分:1)

我认为你必须在不同的平台上运行它并比较结果

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

我怀疑你不能做硬打算,因为尺寸不同。

您可以尝试使用

之类的解决方法
type TBoth = record
  case byte of
    0: ( rec: TVerbInfo);
    1: ( obj: TObject);
  end;

您还可以尝试使用TDictionary<String, TVerbInfo>类型而不是TStringList