将指针分配给 NativeInt 会导致 E2010 类型不兼容

Assigning a Pointer to a NativeInt causes E2010 Incompatible types

Pointer 分配给 NativeInt 变量会导致编译时出现 E2010:

var
  Test : string;
  Ptr : Pointer;
  LocTag : NativeInt;
begin
  Test := 'Hello World';

  Ptr := @Test;
  LocTag := Ptr;
end;

[dcc32 Error] Unit1.pas(34): E2010 Incompatible types: 'NativeInt' and 'Pointer'

我已阅读 Pointer documentation,特别是:

The size of a pointer depends on the operating system and/or the processor. On 32-bit platforms, a pointer is stored on 4 bytes as a 32-bit address. On 64-bit platforms, a pointer is stored on 8 bytes as a 64-bit address.

NativeInt documentation,特别是:

NativeInt represents a subset of the integer numbers. The range of NativeInt depends on the current platform. On 32-bit platforms, NativeInt is equivalent to the Integer type. On 64-bit platforms, NativeInt is equivalent to the Int64 type.

The size of NativeInt is equivalent to the size of the pointer on the current platform

为什么赋值会导致E2010错误?

类型转换 (Tag := NativeInt(Ptr);) 是正确的解决方案吗?

Why does the assignment cause the E2010 error?

因为整数和指针并不完全相同。指针是指向您内存中某个位置的东西;整数不需要这样做(即使它恰好与指针具有相同的大小)。这是关于类型安全和确保你不会犯错误的。通过使用显式转换(您被迫这样做),您可以告诉编译器、阅读您代码的任何人以及您自己,您知道自己在做什么。

Is a typecast (Tag := NativeInt(Ptr);) the right solution?

是的,这正是正确的做法。它也是绝对安全的,因为 (NativeInt) 整数的宽度等于指针的宽度。

Is a typecast (Tag := NativeInt(Ptr);) the right solution?

它会工作,但我认为最好使用 UIntPtr 类型,它被定义为表示一个无符号整数,其值为一个指针。 UIntPtr 用于将指针作为无符号整数处理。

如果您查看 UIntPtr 定义,它是 NativeUInt 的别名。

还有一个 IntPtrNativeInt 的别名。这显然也有效。

UIntPtr比什么都清楚,以后用变量做指针运算更合适。这样可以避免当指针指向高端内存(32 位地址中的 2GB 以上 space)时出现意外结果,因为在这种情况下整数会变为负数。