我刚刚接到将遗留应用程序从32位更新到64位的任务。在审查任务的范围时,我在包含外部(例如平台)标题之前立即发现了以下定义:
#define POINTER_32
我找不到使用这个定义或它有什么效果的东西,但它看起来像是与我的任务直接相关的东西!
它是为了什么?有什么用?立即将其移除是否安全(我认为从长远来看有必要将其移除)?
这是使用MS VC ++ 2008,很快将成为2010年。
答案 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
__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 位应用程序有益:
所有指针仍然是 64 位指针,但系统确保每次内存分配都发生在 2 GB 限制以下,这样如果应用程序截断一个指针,不会丢失任何重要数据。 指针可以被截断为 32 位值,然后通过符号扩展或零扩展扩展到 64 位值。
当设置 /LARGEADDRESSAWARE:NO
时,即使高 32 位没有有效值,指针的大小仍然是 64 位宽。因此,为了为指针节省内存,我们必须将它们声明为 POINTER_32