Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid typecast: convert record to tobject on 64-bit platform

it works on 32-bit platform.but not 64-bit here is the exzample

  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;

can anyone help me? thank you very much

like image 526
taoxl Avatar asked Dec 19 '13 11:12

taoxl


2 Answers

You can try something like this:

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

strList.addObject('verb1', MakeVerbInfoObject(VerbInfo));
like image 60
Uli Gerhardt Avatar answered Nov 15 '22 06:11

Uli Gerhardt


Your cast TObject(VerbInfo) will compile provided that SizeOf(TObject) = SizeOf(TVerbInfo). But TObject is a pointer and so its size varies with architecture. On the other hand, SizeOf(TVerbInfo) does not vary with architecture. Hence the cast can only work on one architecture.

Using casts like this is how you had to do things in pre-generics Delphi. But nowadays, you should be using generic containers.

For instance, if you have a list and the strings are unique then you can use a dictionary:

TDictionary<string, TVerbInfo>

If it is possible for there to be duplicate strings then you would need a new record declaration:

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

And then store a list of these in

TList<TVerbInfo>

One final point is that you should avoid using packed records. These result in mis-aligned data structures and that in turn leads to poor performance.

like image 23
David Heffernan Avatar answered Nov 15 '22 07:11

David Heffernan