【问题标题】:64 bit helper function Handle64toHandle()64 位辅助函数 Handle64toHandle()
【发布时间】:2013-01-14 11:13:40
【问题描述】:

我正在尝试使用 MSVC 64 位编译器解决以下代码的逻辑错误。

这段代码之前在 32 台机器上运行良好。

return ((ULONG) DupThreadHandle);

在 64 位世界中,我了解到任何线程句柄都是 64 位(实际上是 6 字节),所以这段代码显然是错误的,因为目标类型是 ULONG,即 32 位。

但是 msdn 建议使用我在标题中提到的帮助函数,通过包含 basetsd.h 来为 C 代码进行 64 位移植

但我的问题是,这些辅助函数如何在概念上将 6 字节地址更改为 4 字节地址?因为已经将线程放置在某个 6 字节地址。这个 4 字节地址有多大意义? 我不想更改目的地类型。因为问题将是递归警告。

【问题讨论】:

  • 在同一行中,我可以概括这个问题,ptr64toptr() 和 ptrtouint() 如何在 64 位世界中工作?因为如果这个辅助函数提供 32 位值,我需要了解这个 32 位值是如何引用 64 位值的,如果我尝试取消引用这样的 32 位指针?谢谢

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


【解决方案1】:

根据微软here,...

为了便于移植,已决定将这些系统 句柄应保持为 32b 值,符号在 64b 上扩展到 64b 平台。也就是说,各个句柄类型仍然基于 HANDLE 类型,映射到 void *,所以句柄的大小为 指针的大小,即 32b 上的 4 个字节和 64b 上的 8 个字节。 但是,64b 平台上句柄的实际值,(即 有意义的位),适合低 32b,而高位正好 携带标志。

另请参阅this

Handle64toHandle() 函数的效果可以通过简单地在 64 位和 32 位类型之间进行转换来复制自己,但是...这是个大问题.....您必须使用 signed 进行转换类型。如上所述,您使用unsigned 类型的演员会阻碍Microsoft 将地址视为签名数量。更改您的演员表以使用 signed 类型,您应该没问题。但是您需要确保将任何此类地址存储在 signed 32 位类型中,以便稍后将它们正确转换回正确的 64 位类型,而不会丢失最高位的全为状态。如果您由于遗留原因不能这样做(即将它们存储在一个 32 位无符号整数中,这是您无法更改的遗留代码的一部分),那么请确保在进行转换时将这些无符号值转换回有符号值回到 64 位。

【讨论】:

  • 有点困惑,较低的 4 个字节作为地址的一部分有有意义的位,请纠正我,我了解到在 64 位机器中,6 字节地址用于引用内存,所以呢使用辅助函数后剩余 2 个字节?
  • @user2025667 - 不确定您的类适用于什么操作系统/系统,但仅将 8 字节 64 位指针的 6 字节视为重要将是与系统相关的问题。一些 64 位系统可能使用全部 8 个字节。无论如何,我相信 Windows 系统认为指针是“签名的”,与用户相关的东西在地址空间的下半部分(“正”地址)和与操作系统相关的东西在上半部分(“负”地址)。这种情况很容易从 32 位地址空间扩展到 64 位地址空间:考虑如何表示“负”32 位地址:...
  • ...它的高位按定义设置(即 1)。现在用 64 位表示相同的有符号值:低 4 个字节完全相同,我们只需在顶部添加 4 个全 1 字节,将 32 位值符号扩展为 64 位。例如。 32 位 0x80123456 是与 64 位 0xffffffff80123456 完全相同的有符号整数值。如果编译器在适当的转换函数中发出正确的指令来处理这些数字,则 32 位和 64 位指针之间的转换是微不足道的。但是这种简单的转换仅适用于地址空间底部 2GB 和顶部 2GB 中的指针....
  • ...因此,为简单起见,Microsoft 保证只会为句柄分配可以通过这种方式有效转换的指针值(地址)。
  • hello phonetagger ##你是说,在 64 位世界中,windows api 像 malloc()、createwindproc()、_beginthread() 等...只有低 4 个字节和更高的 4 个字节将只有 0 或 f,它们不是地址的一部分?你是这么说的吗?如果是,那么我可以忽略此警告,因为无论如何我只在这种情况下需要较低的 4 个字节?但是如果只有低 4 个字节只有有意义的位,那么我的应用程序将只有 2^31 个地址空间范围可供使用,而不是更多,这与 32 位相同,64 位二进制有什么优势?
猜你喜欢
  • 1970-01-01
  • 2014-01-23
  • 2021-05-24
  • 1970-01-01
  • 1970-01-01
  • 2012-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多