#windows #winapi #mfc
#Windows #winapi #mfc
Вопрос:
В Windows API добавлено несколько *_PTR
типов для поддержки 64-разрядной адресации Win64.
SetItemData(int nIndex,DWORD_PTR dwItemData)
Этот API работает как для 64, так и для 32-разрядных машин, когда я передаю второй параметр как DWORD
.
Я хочу знать, произойдет ли сбой этого конкретного API на 64-разрядной машине, если я передам второй параметр как DWORD
. Как я могу протестировать сценарий сбоя?
Спасибо, Нихил
Ответ №1:
Функция не завершится ошибкой, если вы передадите DWORD
, потому что она вписывается в DWORD_PTR
. Однако указатель гарантированно помещается в a, DWORD_PTR
но не в a DWORD
на 64-разрядных платформах.
Таким образом, этот код правильный:
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.
Комментарии:
1. Вы правы, указатель не поместится в DWORD на 64-разрядной версии, и это приведет к усечению указателя. Как я могу протестировать этот сценарий сбоя, когда мой указатель будет обрезан, и я получу нежелательное значение.
2. Я пробовал это, но я не получаю никакого утверждения: ‘CString str(«»); for (int i=0; i < 20; i ) { str.Format(_T(«строка элемента%d»), i); XcomboCtr. Добавить строку( str ); } int before_ptr = новый int; BOOL bsetItemData= XcomboCtr. SetItemData(0, (DWORD)before_ptr); int *after_ptr = (int )(XcomboCtr. GetItemData(0)); ASSERT(before_ptr == after_ptr); // Сбой. удалить after_ptr; ‘
3. @Nikhil, предполагая, что вы создаете в режиме отладки (
ASSERT
не будет скомпилирован в режиме выпуска), это может означать, что все верхние 32 бита вашего указателя равны нулям. В этом случае это сработает, но вы не можете гарантировать, что все ваши указатели будут такими.