Delphi XE2 64位:记录指针,无效类型转换
我如何重新编码以在 Delphi XE2 的 64 位上编译?
在第一个代码中,我收到错误大小超过 2GB。
第二个,无效类型转换: 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;
How would I recode this to compile on 64-bit for Delphi XE2?
On the first code I get an error size is too large over 2gb.
On the second, Invalid Typecast on: if int64(TMethod(FOnChangeOO[i1])) = int64(TMethod(changeEvent)) then
1)
TExtBool = (no, yes, other);
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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

1) 您应该始终使用 SizeOf(T) 而不是“shr 1/2/3”,因为“shr 2 = div 4”不等于 64 位中的“div SizeOf(Pointer)”。对于 UnicodeString、WideString、IUnknown... 也是如此
2) TMethod 是一个有两个指针的记录。在32位中,两个指针需要8个字节(32bit * 2)。在64位中,两个指针需要16个字节(64bit * 2)。 Int64 不能容纳 128 位。因此,您现在必须直接比较这两个字段,而不是进行强制转换。
1) Instead of "shr 1/2/3" you should always use SizeOf(T) because "shr 2 = div 4" is not equal to "div SizeOf(Pointer)" in 64 bit. The same for UnicodeString, WideString, IUnknown, ...
2) TMethod is a record with two pointers. In 32 bit, the two pointers need 8 bytes (32bit * 2). In 64 bit, the two pointers need 16 bytes (64bit * 2). And an Int64 can't hold 128 bit. So you now have to compare the two fields directly instead of casting it.