在 C++ 中,如何将指针数组初始化为 wchar_t*(结果为 wchar_t**)?

In C++, how do you initialize an array of pointers to wchar_t* (resulting in wchar_t**)?

我正在调用一个需要 wchar_t** 参数的 COM 函数。我想做的是:

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:我尝试​​使用的函数是 GetIDsOfNames,第二个参数是我遇到问题的地方。我想在该参数中传递 3 个名称(我可以使用 wchar_t ptName[] = L"namestring" 成功传递一个名称,但无法弄清楚如何在一个数组中组合多个名称)。

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

您遇到的主要问题是数组必须是指向非常量字符的指针数组,但是您正在尝试使用作为常量字符的字符串文字。

你在网上找到的大多数调用这个函数的例子都忽略了这个问题,因为微软编译器直到最近才允许这种类型的错误(如果你不在严格的标准模式下调用它,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);

您描述为 "I also tried:" 的代码是正确的,但我猜您错误地继续将 &arr 作为 GetIDsOfNames 的参数,而不是 arr

在 C++ 的 COM 编程中,通常的做法是使用包装器 类,为这些底层 C Win32 API 函数提供更方便的 C++ 接口。

字符串文字是 C++ 中的 const 数据。您不能在不使用类型转换的情况下将指向常量的指针分配给指向非常量的指针,例如:

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 数据 复制 到非常量数组中,如 所示。