POINTER_32 - 它是什么,为什么?

时间:2010-08-10 10:04:20

标签: c++ visual-c++ 32bit-64bit

我刚刚接到将遗留应用程序从32位更新到64位的任务。在审查任务的范围时,我在包含外部(例如平台)标题之前立即发现了以下定义:

#define POINTER_32

我找不到使用这个定义或它有什么效果的东西,但它看起来像是与我的任务直接相关的东西!

它是为了什么?有什么用?立即将其移除是否安全(我认为从长远来看有必要将其移除)?

这是使用MS VC ++ 2008,很快将成为2010年。

3 个答案:

答案 0 :(得分:5)

这是一个通常在Windows SDK头文件BaseTsd.h头文件中声明的宏。在32位模式下编译时,它是按照您显示的那样定义的。在64位模式下编译时,它被定义为

 #define POINTER_32 __ptr32

这是一个MSVC编译器扩展,用于在64位代码模型中声明32位指针。对于32位代码,还有64位的风格:

 #define POINTER_64 __ptr64

如果编写64位程序并且需要与另一个进程中的32位代码使用的结构互操作,则可以使用它。例如:

typedef struct _SCSI_PASS_THROUGH_DIRECT32 {
    USHORT Length;
    UCHAR ScsiStatus;
    UCHAR PathId;
    UCHAR TargetId;
    UCHAR Lun;
    UCHAR CdbLength;
    UCHAR SenseInfoLength;
    UCHAR DataIn;
    ULONG DataTransferLength;
    ULONG TimeOutValue;
    VOID * POINTER_32 DataBuffer;      // <== here
    ULONG SenseInfoOffset;
    UCHAR Cdb[16];
}SCSI_PASS_THROUGH_DIRECT32, *PSCSI_PASS_THROUGH_DIRECT32;

答案 1 :(得分:1)

用于绕过 Warning C4244 。在32位和64位模型中提供32位指针

答案 2 :(得分:0)

我的客人是它最初是为 (Very Large Memory) 中的 VLM Alpha AXP 创建的,因为 Windows NT for Alpha 是 the first Windows with some 64-bit support。操作系统仍然是 32 位的,但它有 VLM API 供应用程序在必要时分配大的 64 位内存,因此必须有某种方法在同一程序中声明 32 位和 64 位指针

VLM 返回应用必须存储的 POINTER_64。默认使用POINTER_32/__ptr32,在64位处理代码中将使用POINTER_64/__ptr64

您甚至可以在 Windows 文档和包含文件中看到一些 AXP 的遗物

<块引用>

POINTER_32 在 Ntdef.h 和 Winnt.h 中定义。

#ifdef (__AXP64__)
#define POINTER_32 _ptr32
#else
#define POINTER_32
#endif

Warning C4244

__AXP64__ 用于 Alpha AXP。您还可以在 Ntdef.h 和 Winnt.h 中找到许多其他对 Alpha AXP 的引用,即使 Windows 不再在该平台上运行


另一种用法是在 64 位应用程序中禁用 LARGEADDRESSAWARE 时用于 32 位指针

它与 Linux 中的 x32 ABI 完全相同,其中 long 和指针为 32 位宽

<块引用>

默认情况下,基于 64 位 Microsoft Windows 的应用程序具有数 TB 的用户模式地址空间。有关精确值,请参阅 Memory Limits for Windows and Windows Server Releases。但是,应用程序可以指定系统应为应用程序分配 2 GB 以下的所有内存。如果满足以下条件,则此功能对 64 位应用程序有益:

  • 2 GB 地址空间就足够了。
  • 代码中有很多指针截断警告。
  • 指针和整数可以自由混合。
  • 代码具有使用 32 位数据类型的多态性。

所有指针仍然是 64 位指针,但系统确保每次内存分配都发生在 2 GB 限制以下,这样如果应用程序截断一个指针,不会丢失任何重要数据。 指针可以被截断为 32 位值,然后通过符号扩展零扩展扩展到 64 位值。

Virtual Address Space

当设置 /LARGEADDRESSAWARE:NO 时,即使高 32 位没有有效值,指针的大小仍然是 64 位宽。因此,为了为指针节省内存,我们必须将它们声明为 POINTER_32

How to detect X32 on Windows?