2017-02-17 13 views
0
void file_explore(std::wstring str) { 
    ITEMIDLIST *pIDL = ILCreateFromPath(str.c_str()); 
    if (NULL != pIDL) { 
     SHOpenFolderAndSelectItems(pIDL , 0 , 0 , 0); 
     ILFree(pIDL); 
    } else { 
     std::wstring p = str.substr(0 , str.find_last_of('\\')); 
     ShellExecute(NULL , L"explore" , p.c_str() , NULL , NULL , SW_SHOWNORMAL); 
    } 
}  

Вышеприведенных компилируется без предупреждения для 32-х, но с 64-битным, однако я получаю предупреждение c4090 документацию: https://msdn.microsoft.com/en-us/library/k77bkb8d.aspx состояния, что это ошибка переменного тока, и я буду получать C2440 для C++ но я использую C++.предупреждение C4090: «инициализация»: разные «__unaligned» отборочные

Строка кода жаловалась на это:

ITEMIDLIST *pIDL = ILCreateFromPath(str.c_str()); 

Как исправить эту проблему для 64-битной сборки?

+0

Ваш проект, вероятно, определен как 'STRICT_TYPED_ITEMIDS', но вы используете общий' ITEMIDLIST * '. [ILCreateFromPath] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd378420.aspx) возвращает 'PIDLIST_ABSOLUTE'. Это один из строгих [ITEMIDLIST] (https://msdn.microsoft.com/en-us/library/windows/desktop/bb773321.aspx), и вы должны назначить его одному типу. – IInspectable

+0

Вы можете избавиться от предупреждения, используя тип, рекомендованный статьей MSDN: 'PIDLIST_ABSOLUTE pIDL = ILCreateFromPath (...); Использование LPITEMIDLIST также решает. –

+0

^^ спасибо, в прошлый раз, когда я посетил, в рейтинге было какое-то мнение, но они, похоже, исчезли. – User666

ответ

0

LPITEMIDLIST определяется как typedef ITEMIDLIST __unaligned *LPITEMIDLIST, поэтому принятие результата ITEMIDLIST * теряет __unaligned модификатор. Я не уверен, как это относится к 32-битным и 64-битным.

Как отметил Ханс Пассант, использование typedef решает проблему. В моем случае я использую std::unique_ptr, который хочет использовать базовый тип, а не указатель, поэтому мне нужен не указатель typedef. Потому что это может быть тангенциальным интерес для людей, наткнуться на этот ответ, я помещу в том, как я делаю использование std::unique_ptr с ILCreateFromPath, включая пользовательский Deleter для удовольствия:

auto deleter = [](LPITEMIDLIST ptr) { ILFree(ptr); }; 
using itemidlistptr_t = std::unique_ptr< 
    std::remove_ptr_t<LPITEMIDLIST>, decltype(deleter)>; 
auto dir = itemidlistptr_t(ILCreateFromPathW(folder.c_str()), deleter); 

Использования std::remove_pointer_t немного окольный , но мне здесь нравится, а не непосредственно упоминать __unaligned.