C ++: использование std :: wstring в функции API - PullRequest
3 голосов
/ 29 июня 2010

Я использую API-функцию SHGetSpecialFolderLocation .Мое приложение настроено на «Использовать набор символов Unicode».

Вот что у меня есть:

int main ( int, char ** )
{
    LPITEMIDLIST pidl;
    HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &pidl);


    /* Confused at this point */
    wstring wstrPath;

    wstrPath.resize ( _MAX_PATH );
    BOOL f = SHGetPathFromIDList(pidl, wstrPath.c_str () );
    /* End confusion */

Я получаю ошибку:

error C2664: 'SHGetPathFromIDListW' : cannot convert parameter 2 from 'const wchar_t *' to 'LPWSTR'

Может кто-нибудь помочь?Какой правильный C ++ способ сделать это?

Спасибо!

Ответы [ 5 ]

6 голосов
/ 29 июня 2010

Второй параметр - это параметр out , поэтому вы не можете просто передать c_str (то есть const) напрямую. Наверное, было бы проще всего сделать:

wchar_t wstrPath[MAX_PATH];
BOOL f = SHGetPathFromIDList(pidl, wstrPath);

MAX_PATH в настоящее время 260 символов.

1 голос
/ 29 июня 2010

Вы можете получить адрес 1-го элемента массива в basic_string как указатель на доступные для записи строковые данные. Хотя стандарт C ++ не гарантирует, что этот блок памяти должен быть непрерывным, это безопасно во всех известных реализациях ( Насколько плох код, использующий std :: basic_string в качестве непрерывного буфера ).

std::wstring path(_MAX_PATH, L'\0');
BOOL f = SHGetPathFromIDList(pidl, &path[0]);
1 голос
/ 29 июня 2010

wstring::c_str() возвращает const wchar_t* и является только для чтения . LPWSTR не является типом const, и этот параметр является выходным параметром. Вам нужно будет выделить буфер самостоятельно. Вы могли бы сделать что-то вроде этого:

wchar_t buf[MAX_PATH] = {0};
BOOL f = SHGetPathFromIDList( pidl, buf );
wstring wstrPath = buf;
1 голос
/ 29 июня 2010

std::basic_string::c_str() возвращает константный буфер в свою память.Если вы хотите изменить строку, вам придется сделать что-то вроде этого:

wstring wstrPath;
wstrPath.resize( MAX_PATH );
BOOL f = SHGetPathFromIDList(pidl, &wstrPath[0]);
wstrPath.erase(
   std::find(wstrPath.begin(), wstrPath.end(), L'\0'), wstrPath.end()
); //Throw away unused buffer space

РЕДАКТИРОВАТЬ: должно также работать, если вы не боитесь библиотек C (хотяЯ не проверял это, как я проверял реализацию выше):

wstring wstrPath;
wstrPath.resize( MAX_PATH );
BOOL f = SHGetPathFromIDList(pidl, &wstrPath[0]);
wstrPath.resize(wcslen(wstrPath.c_str()));
0 голосов
/ 29 июня 2010

wstring :: c_str () не позволяет вам изменять свой внутренний буфер таким образом.Самый простой способ - создать буфер wchar_t самостоятельно и передать его конструктору wstring:

wchar_t buf[MAX_PATH];
BOOL f = SHGetPathFromIDList(pidl, buf );
wstring wstrPath(buf);
...