如何在Win x64中在32位和64位应用程序之间共享HWND?

23

MSDN告诉我,窗口句柄(HWND)可以在32位和64位应用程序之间共享,在进程间通信中(MSDN)。但是,在Win32中,HWND是32位,而在64位Windows中,它是64位。那么如何共享句柄呢?

我猜同样的问题也适用于命名对象的句柄,例如互斥体、信号量和文件句柄。

5个回答

21
正如 Daniel Rose 在上面指出的那样,MSDN 文档现在陈述:

... 截断句柄(从64位传递到32位时)或者扩展句柄(从32位传递到64位时)是安全的。

此处仍存在一些混淆,因为 WOW64 开发人员告诉我零扩展是正确的方式。如果您正在编写一个 64 位模块,并从 32 位模块获取句柄,则最安全的做法可能是仅比较句柄的低 32 位(即截断)。否则,您可能会在扩展方式上遇到问题。


13

我刚刚收到了一封来自微软WOW64开发人员的电子邮件,证实:

句柄是32位的,可以安全地截断/零扩展。这适用于内核对象句柄和USER/GDI句柄。


9

它们可以被共享的事实是否意味着在Win64进程中仅使用了低32位?Windows句柄是索引而不是指针,至少据我所知,因此,除非Microsoft想要允许超过2 ^ 32个窗口/文件/互斥等句柄,否则在Win64上没有理由使用void *的高32位。


8
我明白了你的意思,但是在MSDN中似乎没有具体说明只使用并且将来只会使用低32位,因此这样做是安全的。尽管了解当前窗口句柄的底层实现方式,但由于其未被记录文档,不能保证在Windows的未来版本中不会更改。 - Marc Durdin
1
如果有一件微软做得好的事情,那就是保持向后兼容性。我同意找到一些明确的陈述会很好,但看起来你只能得到一个隐含的陈述。也许你应该在其中一个论坛中询问,比如 microsoft.public.windows.64bit.generalmicrosoft.public.windows.app_compatibility(请参阅http://www.aumha.org/nntp.php)。一些微软开发人员肯定清楚... - Tim Sylvester
1
@Marc: "MSDN 中的具体文档" 就是你提供链接的那个声明。它并没有真正说明只使用了低 32 位,实际上我期望 Win64 设置至少一个高位 - 只是为了发现已被截断的句柄 - 但是低 32 位应足以唯一标识窗口。 - MSalters
2
@MSalters,如果微软在Win64中设置了高位,则从Win32传递的句柄的HWND比较将会中断。您的陈述是为什么我们需要在这些情况下具有清晰度而不仅仅是假设和隐含猜测,因此截断是允许的一个明显例子。换句话说,MSDN应该说类似于:“在Win64中,HWND仅使用低32位,而上32位始终为零。因此,要将HWND传递给Win32,请将其截断为DWORD32。”那是明确的、具体的文档。 - Marc Durdin
@Marc:我不同意。截断是显而易见的,事实上是使用 Win32 API 获得的 HWND 与使用 Win64 API 获得的 HWND 进行比较的正确方式。无论哪一侧的代码(x86/x64)实际执行比较,都应该进行此截断。 - MSalters
7
@MSalters MSDN现在明确将截断/符号扩展作为正确的方式:http://msdn.microsoft.com/en-us/library/aa384203.aspx - Daniel Rose

2
请查看微软接口定义语言(MIDL)移植指南第12页(http://msdn.microsoft.com/en-us/library/ms810720.aspx),其中提到USER和GDI句柄是符号扩展的32位值。

1

我认为你在一般情况下谨慎是正确的。然而,MSDN声称它们可以被共享,这对我们程序员来说是一个合同。他们不能说“今天分享”,然后明天就“不再分享”,否则会破坏大量软件。

同样地,为了让x64和32位软件在同一台机器上同时运行,并且让所有人都能相处融洽,HWNDs(以及许多HANDLEs)必须继续保持32位并且兼容。

我想我想说的是,至少在Windows 7的生命周期内,以及可能的Windows“下一个”版本中,我认为这是一个非常安全的赌注。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接