64位应用程序上的Windows HANDLE的范围是多少?

时间:2013-08-16 05:50:27

标签: windows winapi 64-bit handle

在WinAPI上,HANDLE类型定义为void*,因此在64位应用程序中,HANDLE值的范围可以从018446744073709551615 。 但这在实践中是真的吗?是否有任何文档指定了HANDLE的整体范围?

例如,如果有人希望将这个HANDLE作为int32_t存储在完全正常的32位应用程序上,但在64位应用程序上则存在疑问。

3 个答案:

答案 0 :(得分:23)

MSDN声明:

Interprocess Communication Between 32-bit and 64-bit Applications

  

64位版本的Windows使用32位句柄来实现互操作性。   在32位和64位应用程序之间共享句柄时,只有   低32位是重要的,因此截断句柄是安全的   (将其从64位传递到32位时)或对句柄进行符号扩展   (当它从32位传递到64位时)。可以共享的句柄   包括用户对象的句柄,例如windows(HWND),GDI句柄   笔和画笔(HBRUSH和HPEN)等对象和句柄   命名对象,如互斥锁,信号量和文件句柄。

还值得注意的是,该页面上添加了此评论:

  

跨进程边界共享此类句柄的正确方法是   零扩展32位处理为64位,反之亦然   64位处理为32位,丢弃最高位。

注意"符号扩展"之间的区别手柄与"零延伸"手柄。

编辑:从对这个问题的删除答案中看到的讨论判断,我认为签名扩展32位句柄以达到64位句柄而非零的重要性 - 扩展它是为了保持对句柄的INVALID_HANDLE_VALUE值的适当处理。

答案 1 :(得分:3)

我希望知道它在哪里被记录,但是我的一位同事坚持认为64位HWND句柄总是适合32位。我从来没有见过一个不真实的案例,但不能说出未来或者记录在哪里。关于其他句柄,比如说,HTREEITEM ....它们是完整的64位,而且我一直认为它们太适合32位。

答案 2 :(得分:0)

要添加到先前的正确答案,请注意,HWND也是跨进程的有效句柄。其他任何void *句柄(如HBRUSH,HBITMAP等)都可能是可截断的,因为只有低32位才是有效的,但在其自身进程之外无效。

对于GDI对象,它可能起作用,因为它们实际上是索引(请参见https://docs.microsoft.com/en-us/previous-versions/ms810501(v=msdn.10)

  

好吧,这里发生的是GDI对象的句柄在内部   实现为驻留在客户端上的句柄表中的偏移量   Win32子系统的一侧。 (请记住,Win32客户端是一个DLL   驻留在基于Win32的应用程序的地址空间中,并且   换句话说,句柄表保留在   每个进程为基础,但未对进程进行标记。那意味着   属于进程A的对象的句柄可能同时发生   看起来像进程B上下文中的有效句柄。因此,   B的SelectObject可能会成功,但是B实际上会选择一个   与其设备上下文完全不同的对象-更糟的是,正确的对象   一。选择正确的对象可能会更糟,因为这些对象可能   巧合的是,所以您认为它可行,但是该应用程序   以后会怪异地表现。因此,请勿将句柄传递给GDI对象   应用之间;他们有完全不同的含义   不同的过程。

HWND是对此的记录例外。