为何添加L前缀后仍出现char*转const wchar_t*编译错误?
编译错误:无法将char转换为const wchar_t的解决办法
我在main.cpp中调用以下代码:
uintptr_t moduleBase = GetModuleBaseAddress(pid, L"Game.exe");对应的函数定义是:
uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName) { uintptr_t modBaseAddr = 0; HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId); if (hSnap != INVALID_HANDLE_VALUE) { MODULEENTRY32 modEntry; modEntry.dwSize = sizeof(modEntry); if (Module32First(hSnap, &modEntry)) { do { if (!_wcsicmp(modEntry.szModule, modName)) { modBaseAddr = (uintptr_t)modEntry.modBaseAddr; break; } } while (Module32Next(hSnap, &modEntry)); } } CloseHandle(hSnap); return modBaseAddr; }明明给字符串加了
L前缀,函数参数也是const wchar_t*,却仍收到编译错误:error: cannot convert 'char*' to 'const wchar_t*'
问题原因
核心是字符集不匹配:
- 当项目默认使用多字节字符集时,
MODULEENTRY32会被自动映射为ANSI版本的MODULEENTRY32A,此时modEntry.szModule是char*类型。 - 你传入的
L"Game.exe"是宽字符(wchar_t*),函数参数也是const wchar_t*,但编译器会因为结构体成员的char*类型,在类型检查时抛出转换错误。
解决方案
方案1:切换项目为Unicode字符集
在Visual Studio中操作:
- 右键项目 → 属性 → 配置属性 → 常规 → 字符集,选择使用Unicode字符集。
设置后,MODULEENTRY32会自动变为宽字符版本的MODULEENTRY32W,szModule类型变为wchar_t*,和你的函数参数、传入的字符串完全匹配,编译错误会直接消失。
方案2:显式使用宽字符版本的结构体与函数
如果不想修改全局字符集,可以手动指定宽字符相关的类型和函数:
uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName) { uintptr_t modBaseAddr = 0; HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId); if (hSnap != INVALID_HANDLE_VALUE) { MODULEENTRY32W modEntry; // 显式声明宽字符版本结构体 modEntry.dwSize = sizeof(modEntry); if (Module32FirstW(hSnap, &modEntry)) // 调用宽字符版本的Module32First { do { if (!_wcsicmp(modEntry.szModule, modName)) { modBaseAddr = (uintptr_t)modEntry.modBaseAddr; break; } } while (Module32NextW(hSnap, &modEntry)); // 调用宽字符版本的Module32Next } } CloseHandle(hSnap); return modBaseAddr; }
这样即使项目是多字节字符集,也能保证结构体成员和函数都是宽字符类型,和传入的L"Game.exe"类型兼容。
额外提示
_wcsicmp是宽字符版本的不区分大小写字符串比较函数,和wchar_t*类型匹配,无需修改。- 若使用GCC等其他编译器,需确保定义了
UNICODE宏,或者手动指定宽字符相关的编译选项。
内容的提问来源于stack exchange,提问作者user21138718
相关产品推荐
相关产品推荐

