Windows API 中添加了一些
*_PTR
类型以支持 Win64 的 64 位寻址。
SetItemData(int nIndex,DWORD_PTR dwItemData)
当我将第二个参数作为
DWORD
传递时,此 API 适用于 64 和 32 位机器。
我想知道,如果我将第二个参数作为
DWORD
传递,这个特定的 API 在 64 位机器上是否会失败。如何测试失败场景?
谢谢, 尼基尔
如果您传递
DWORD
,该函数不会失败,因为它适合 DWORD_PTR
。然而,在 64 位平台上,指针保证适合 DWORD_PTR
,但 not 适合 DWORD
。
因此,这段代码是正确的:
int *before_ptr = new int;
yourListBox.SetItemData(index, (DWORD_PTR) before_ptr);
int *after_ptr = (int *) yourListBox.GetItemData(index);
ASSERT(before_ptr == after_ptr); // Succeeds.
delete after_ptr; // Works.
但是这段代码是错误的,并且会默默地将指针截断为低 32 位:
int *before_ptr = new int;
yourListBox.SetItemData(index, (DWORD) before_ptr);
int *after_ptr = (int *) yourListBox.GetItemData(index);
ASSERT(before_ptr == after_ptr); // Fails.
delete after_ptr; // Undefined behavior, might corrupt the heap.
从 VS2010 迁移到 VS2019 时,我们遇到了“DWORD bug”的确切问题。 VS2010 中内置的 64 位应用程序的指针值的高 32 位始终为零。 VS2019 中构建的 64 位应用程序的指针值在高 32 位中有时不为零。这会导致某些应用程序间歇性崩溃。似乎无论出于何种原因,VS2010 中构建的代码都没有利用可用于 64 位应用程序的 64 位虚拟地址空间。而 VS2019 使用了它。我认为了解这是否是由于链接器差异或与加载图像执行有关而引起的会很有趣。