C++报错:char[256]无法转换为std::wstring 构造函数不匹配
错误原因
两个编译错误都来自字符集不匹配:
你代码中使用的MODULEENTRY32是Windows API的ANSI版本结构体,它的szModule成员类型是char[256],但你尝试用这个窄字符数组直接构造std::wstring,std::wstring只能接收wchar_t类型的字符数组作为构造参数,自然找不到匹配的构造函数,触发类型转换失败的报错。
出现这个问题的本质是Windows API的字符集宏机制:不带A/W后缀的API、结构体会根据编译时是否定义UNICODE宏,自动展开为窄字符(A后缀)或宽字符(W后缀)版本,你当前编译环境没有定义UNICODE宏,所以默认展开的是窄字符版本,和你代码里用的std::wstring逻辑不匹配。
修复方法
推荐方案:统一使用宽字符API(和入参类型匹配)
将所有和模块枚举相关的结构体、API替换为明确的宽字符版本,避免宏展开带来的类型不匹配问题,同时修正代码里的两个隐藏逻辑bug:
- 快照句柄创建失败时返回值是
INVALID_HANDLE_VALUE(值为-1),不是空指针,原判断逻辑会在快照创建失败时错误调用CloseHandle - 模块枚举需要先调用
Module32First获取第一个条目,再循环调用Module32Next遍历剩余条目,原逻辑会漏掉进程的主exe模块
修正后的完整lambda代码如下:
auto get_proc_base = [&](std::wstring moduleName) { MODULEENTRY32W entry = { }; entry.dwSize = sizeof(MODULEENTRY32W); std::uintptr_t result = 0; const auto snapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, r6_pid); // 先判断快照是否有效 if (snapShot == INVALID_HANDLE_VALUE) { return result; } // 先取第一个模块再循环遍历 if (Module32FirstW(snapShot, &entry)) { do { if (std::wstring(entry.szModule) == moduleName) { result = reinterpret_cast<std::uintptr_t>(entry.modBaseAddr); break; } } while (Module32NextW(snapShot, &entry)); } CloseHandle(snapShot); return result; };
备选方案:统一使用窄字符逻辑
如果你不需要处理带非ASCII字符的模块名,也可以把lambda入参改为窄字符串类型,适配当前默认的ANSI版本API:
- 将入参
std::wstring moduleName改为std::string moduleName - 比较时直接用
std::string(entry.szModule) == moduleName
这个方案兼容性差,遇到中文等非ASCII模块名容易出现匹配失败的问题,不推荐使用。
内容的提问来源于stack exchange,提问作者Maurice Moss
相关产品推荐
相关产品推荐

