В C ++, как вы инициализируете массив указателей на wchar_t * (что приводит к wchar_t **)? - PullRequest
0 голосов
/ 18 февраля 2020

Я вызываю функцию COM, для которой требуется аргумент wchar_t**. Я хотел бы сделать следующее:

wchar_t* arr[3] = {L"str1", L"str2", L"str3"};

Я получаю const wchar_t**, который компилятор отклоняет.

Я также пытался:

wchar_t* arr[3];
wchar_t p1[] = L"str1";
wchar_t p2[] = L"str2";
wchar_t p3[] = L"str3";
arr[0] = p1;
arr[1] = p2;
arr[2] = p3;

Я получаю ответ wchar_t* (*)[3], который компилятор также отвергает.

Я новичок в C ++ и действительно борюсь с тем, как обрабатываются строковые литералы.

ETA: функция I ' я пытаюсь использовать это GetIDsOfNames и второй параметр, где у меня возникла проблема. Я хочу передать 3 имени в этом параметре (я могу успешно передать одно имя с помощью wchar_t ptName[] = L"namestring", но не могу понять, как объединить несколько имен в массиве).

HRESULT GetIDsOfNames(  
REFIID   riid,  
LPOLESTR *rgszNames, 
UINT     cNames,  
LCID     lcid,  
DISPID   *rgDispId  
); 

Ответы [ 2 ]

2 голосов
/ 18 февраля 2020

Основная проблема, с которой вы сталкиваетесь, состоит в том, что массив должен быть массивом указателей на непостоянные символы, однако вы пытаетесь использовать строковые литералы, которые являются постоянными символами.

Большинство примеров, которые вы можете найти в Интернете вызов этой функции игнорирует эту проблему, потому что компилятор Microsoft допускал эту ошибку до недавнего времени (и до сих пор делает, если вы не вызываете ее в строгом стандартном режиме, AFAIK).

Чтобы настроить массив в стандарте C ++ код может быть:

wchar_t p1[] = L"str1";
wchar_t p2[] = L"str2";
wchar_t p3[] = L"str3";
wchar_t* arr[3] = { p1, p2, p3 };

и поэтому весь вызов может быть:

DISPID dispid[3];
HRESULT result = iFoo->GetIDsOfNames( IID_NULL, arr, 3, LOCALE_SYSTEM_DEFAULT, dispid);

Код, который вы описали как «Я также пытался:», был бы правильным, но я думаю, вы ошиблись далее в качестве аргумента для GetIDsOfNames вместо arr ставили &arr. В программировании COM на C ++ обычная практика - использовать классы-обертки, которые предоставляют более удобный интерфейс C ++ для этих базовых C Win32 API функции.

1 голос
/ 18 февраля 2020

Строковый литерал - это const данные в C ++. Вы не можете назначить указатель на const указателю на неконстантный без использования typecast, например:

const wchar_t* arr[3] =
{
    L"str1",
    L"str2",
    L"str3"
};

...->GetIDsOfNames(..., const_cast<LPOLESTR*>(arr), 3, ...);

В качестве альтернативы:

wchar_t* arr[3] =
{
    const_cast<wchar_t*>(L"str1"),
    const_cast<wchar_t*>(L"str2"),
    const_cast<wchar_t*>(L"str3")
};

...->GetIDsOfNames(..., arr, 3, ...);

В противном случае вы нужно будет скопировать данных const в неконстантные массивы, как показывает ответ MM .

...