错误C7034:数组不能使用括号初始化器进行初始化。

5
我正在尝试编写一个本地的Node插件,用于枚举Windows机器上的所有窗口,并将它们的标题以数组形式返回给JS端。但是,我被这个错误难住了:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(655): error C3074: an array cannot be initialized with a parenthesized initializer [C:\xampp\htdocs\enum-windows\build\enumWindows.vcxproj]

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(773): note: see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,char(&)[255]>(_Objty (*),char (&)[255])' being comp iled with [ _Ty=char [255], _Objty=char [255] ]

据我所知,我没有执行数组的括号初始化?
#include <vector>
#include <node.h>
#include <v8.h>
#include <windows.h>
#include <stdio.h>

using namespace node;
using namespace v8;

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM ptr) {
    std::vector<char[255]>* windowTitles =
        reinterpret_cast<std::vector<char[255]>*>(ptr);

    if (IsWindowVisible(hWnd)) {
        int size = GetWindowTextLength(hWnd);
        char buff[255];
        GetWindowText(hWnd, (LPSTR) buff, size);
        windowTitles->push_back(buff);
    }

    return true;
};

void GetWindowTexts(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);
    Local<Array> arr = Array::New(isolate);
    std::vector<char[255]> windowTitles;

    EnumWindows(
        &EnumWindowsProc, 
        reinterpret_cast<LPARAM>(&windowTitles));

    for (unsigned int i = 0; i < windowTitles.size(); i++) {
        const char* ch = reinterpret_cast<const char*>(windowTitles.at(i));
        Local<String> str = String::NewFromUtf8(isolate, ch);
        arr->Set(i, str);
    }

    args.GetReturnValue().Set(arr);
}

void init(Handle<Object> exports, Handle<Object> module) {
    NODE_SET_METHOD(module, "exports", GetWindowTexts);
}

NODE_MODULE(enumWindows, init);

我认为错误与这行代码有关:

windowTitles->push_back(buff);

也许我的方法有些幼稚。

我不熟悉Visual Studio,但我相信它应该会打印出带有行号的错误信息,这样你就可以确定哪一行引起了错误。 - Mine
1
我建议使用std::string的向量。在C++11中,可以安全地使用&s[0]将字符串数据写入。此外,对于LPSTR的强制转换看起来非常可疑。在您的情况下,强制转换什么也没做。 - chris
const char* ch = reinterpret_cast<const char*>(windowTitles.at(i)); 看起来没问题。我发现你可以通过检查以下编译器错误来查看哪一行导致了模板实例化错误。所以它将从xmemory开始,就像这种情况一样,然后可能会跟随另一个标准库的另一行,但最终你会在你的源文件中得到一个行号。只需继续阅读即可。一旦你看到这一行,就变得更容易了。 - wally
看起来问题出在 windowTitles->push_back(buff); 这一行。 - wally
@flatmouse 经过仔细查看堆栈跟踪,你是正确的。 - sdgluck
@chris 我移除了对 LSPTR 的强制转换,它的缺失并没有引起任何额外的问题。谢谢! - sdgluck
1个回答

12

问题在这里出现:

windowTitles->push_back(buff);

因为你无法将数组存储在std::vector中。

来自链接的回答:

标准库容器存储的对象必须可复制和可分配,而数组既不是复制也不是可分配的。

也许可以使用类似以下内容。数组已被替换为std::array<char,255>

BOOL CALLBACK EnumWindowsProc(HWND hWnd,LPARAM ptr)
{
    std::vector<std::array<char,255>>* windowTitles =
        reinterpret_cast<std::vector<std::array<char,255>>*>(ptr);

    if (IsWindowVisible(hWnd)) {
        int size = GetWindowTextLength(hWnd);
        std::array<char,255> buff;
        GetWindowText(hWnd,(LPWSTR)buff.data(),size);
        windowTitles->push_back(buff);
    }

    return true;
};

我不得不将其转换为LPSTR而不是LPWSTR。现在它生成了一个窗口标题数组,但有些被截断了。但这是进步!非常感谢。 - sdgluck
1
非常感谢。我之前有启用 Unicode,但是我忘记了切换到 LPWSTR 进行测试。 - wally

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接