64位机器上的DWORD和DWORD_PTR

6

为了支持Win64的64位寻址,Windows API中添加了几种*_PTR类型。

SetItemData(int nIndex,DWORD_PTR dwItemData)

当我将第二个参数设置为DWORD时,此API适用于64位和32位机器。

我想知道,如果我将第二个参数设置为DWORD,这个特定的API是否会在64位机器上失败。我如何测试失败场景?

谢谢, Nikhil

1个回答

6

如果你传递了一个DWORD,那么该函数将不会失败,因为它可以适应DWORD_PTR。然而,指针被保证可以适应DWORD_PTR,但在64位平台上不能适应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.

你是正确的,在64位系统中指针无法适应DWORD,因此会截断指针。我该如何测试这种失败场景,以便我的指针被截断并且我得到了不希望得到的值。 - Nikhil
我尝试了这个,但是我没有得到任何断言:'CString str(""); for (int i=0;i < 20;i++) { str.Format(_T("item string %d"), i); XcomboCtr.AddString( str ); } int *before_ptr = new int;BOOL bsetItemData= XcomboCtr.SetItemData(0, (DWORD)before_ptr);int after_ptr = (int)( XcomboCtr.GetItemData(0));ASSERT(before_ptr == after_ptr); // 失败。delete after_ptr;' - Nikhil
@Nikhil,假设您正在调试模式下构建(ASSERT不会在发布模式下编译),这可能意味着您指针的高32位都是零。在这种情况下,它将工作,但您不能保证所有指针都是这样的。 - Frédéric Hamidi

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