Delphi XE2 64bit:记录指针,无效类型转换

Posted

技术标签:

【中文标题】Delphi XE2 64bit:记录指针,无效类型转换【英文标题】:Delphi XE2 64bit: record pointer, invalid typecast 【发布时间】:2011-10-22 22:30:09 【问题描述】:

如何重新编码以在 64 位上为 Delphi XE2 编译?

在第一个代码中,我得到一个错误 size is too large over 2gb.

第二个,Invalid Typecast on: if int64(TMethod(FOnChangeOO[i1])) = int64(TMethod(changeEvent)) then

1) TExtBool =(不,是,其他);

  TAByte          = array [0..maxInt      -1] of byte;
  TAShortInt      = array [0..maxInt      -1] of shortInt;
  TAChar          = array [0..maxInt div sizeOf(Char)-1] of Char;
  TAAnsiChar      = array [0..maxInt      -1] of AnsiChar;
  TAWideChar      = array [0..maxInt shr 1-1] of WideChar;
  TABoolean       = array [0..maxInt      -1] of boolean;
  TAExtBool       = array [0..maxInt      -1] of TExtBool;
  TAWord          = array [0..maxInt shr 1-1] of word;
  TASmallInt      = array [0..maxInt shr 1-1] of smallInt;
  TACardinal      = array [0..maxInt shr 2-1] of cardinal;
  TAInteger       = array [0..maxInt shr 2-1] of integer;
  TAPointer       = array [0..maxInt shr 2-1] of pointer;
  TAString        = array [0..maxInt shr 2-1] of string;
  TAAnsiString    = array [0..maxInt shr 2-1] of AnsiString;
  TAWideString    = array [0..maxInt shr 2-1] of WideString;
  TAUnicodeString = array [0..maxInt shr 2-1] of UnicodeString;
  TAIUnknown      = array [0..maxInt shr 2-1] of IUnknown;
  TAInt64         = array [0..maxInt shr 3-1] of int64;

2)

TMethod = record code, data: pointer; end;
  TIListChangeEventOO = procedure (const list: ICustomBasicList; const item: IBasic;
                                   beforeChange: boolean;
                                   changeType: TChangeType; oldIndex, index: integer) of object;
  ICustomBasicList = interface (IList) ['EE6D35A0-5F85-11D3-A52D-00005A180D69']
  TChangeType = (lctUnchanged, lctChanged, lctNew, lctDeleted);
 IBasic = interface ['53F8CE42-2C8A-11D3-A52D-00005A180D69']


procedure TICustomBasicList.RegisterChangeEvent(changeEvent: TIListChangeEventOO);
var i1 : integer;
begin
  FSection.Enter;
  try
    if CheckValid then begin
      for i1 := 0 to high(FOnChangeOO) do
        if int64(TMethod(FOnChangeOO[i1])) = int64(TMethod(changeEvent)) then
          exit;
      i1 := Length(FOnChangeOO);
      SetLength(FOnChangeOO, i1 + 1);
      FOnChangeOO[i1] := changeEvent;
    end;
  finally FSection.Leave end;
end;

function TICustomBasicList.UnregisterChangeEvent(changeEvent: TIListChangeEvent) : boolean;
var i1, i2 : integer;
begin
  result := false;
  FSection.Enter;
  try
    i2 := high(FOnChange);
    for i1 := i2 downto 0 do
      if @FOnChange[i1] = @changeEvent then begin
        FOnChange[i1] := FOnChange[i2];
        dec(i2);
        result := true;
        FSuccess := true;
      end;
    if result then SetLength(FOnChange, i2 + 1)
    else           SetLastError(ERROR_FILE_NOT_FOUND);
  finally FSection.Leave end;
end;

【问题讨论】:

如果能够在指针上使用索引而不是用愚蠢的固定大小数组类型声明来解决问题会更好 【参考方案1】:

1) 您应该始终使用 SizeOf(T) 而不是“shr 1/2/3”,因为“shr 2 = div 4”不等于 64 位中的“div SizeOf(Pointer)”。 UnicodeString、WideString、IUnknown、...

2) TMethod 是一个有两个指针的记录。在 32 位中,两个指针需要 8 个字节(32 位 * 2)。在 64 位中,两个指针需要 16 个字节(64 位 * 2)。而且 Int64 不能容纳 128 位。因此,您现在必须直接比较这两个字段,而不是强制转换。

if (TMethod(FOnChangeOO[i1]).Data = TMethod(changeEvent).Data) and
   (TMethod(FOnChangeOO[i1]).Code = TMethod(changeEvent).Code) then

【讨论】:

关于第 1 点,数组类型索引中的所有 shr 都用于定义一些最多存储 maxInt 字节的数组。这在 64 位模式下不再有意义,其中一个数组可以存储超过 maxInt 个字节。恕我直言,您应该保留它并强制编译器不使用范围检查。

以上是关于Delphi XE2 64bit:记录指针,无效类型转换的主要内容,如果未能解决你的问题,请参考以下文章

Delphi TADOStoredProc / D6 和 RAD Studio XE2 最近的故障

Delphi - 需要 XE2 代码到 Delphi7。使用wininet下载文件

DELPHI XE2 ide设置技巧

怎么设置禁止delphi Xe2 自动检查更新

有没有 Delphi XE2 样式库?

使用 Delphi XE2 的 AnimateWindow