E0167 “CHAR *”类型的参数与“const wchar_t *”类型的参数不兼容
Posted
技术标签:
【中文标题】E0167 “CHAR *”类型的参数与“const wchar_t *”类型的参数不兼容【英文标题】:E0167 argument of type "CHAR *" is incompatible with parameter of type "const wchar_t *" 【发布时间】:2022-01-23 19:56:42 【问题描述】:我正在编写一个允许我在流程上画线的项目,但出现 2 个错误:
E0167: argument of type "CHAR *" is incompatible with parameter of type "const wchar_t *"
C2664: 'int _wcsicmp(const wchar_t *,const wchar_t *)': cannot convert argument 1 from 'CHAR [260]' to 'const wchar_t *'
我已将项目设置从 Unicode 更改为多字节。它解决了这个问题,但在切换后它在代码的另一部分给了我另一个错误。
这里是来源:
DWORD GetProcId(const wchar_t* procName)
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
do
if (!_wcsicmp(procEntry.szExeFile, procName))
procId = procEntry.th32ProcessID;
break;
while (Process32Next(hSnap, &procEntry));
uintptr_t GetModuleBaseAddress(DWORD dwPid, const char* moduleName)
uintptr_t dwBase = 0;
do
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwPid);
if (hSnapshot == INVALID_HANDLE_VALUE) continue;
MODULEENTRY32 ModuleEntry32;
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &ModuleEntry32))
do
if (!strcmp(ModuleEntry32.szModule, (LPSTR)moduleName))
dwBase = (DWORD)ModuleEntry32.modBaseAddr;
break;
while (Module32Next(hSnapshot, &ModuleEntry32));
CloseHandle(hSnapshot);
while (!dwBase);
return dwBase;
当字符集使用 Unicode 时,if (!_wcsicmp(procEntry.szExeFile, procName))
行不会给我任何错误。但是,在 GetModuleBase()
中,ModuleEntry32
行中的 if (!strcmp(ModuleEntry32.szModule, (LPSTR)moduleName))
给了我上面显示的两个错误。
当我将字符集设置为多字节时,错误在if (!_wcsicmp(procEntry.szExeFile, procName))
行中切换为procEntry
。
我似乎无法弄清楚问题所在。它一直告诉我argument of type "CHAR *" is incompatible with parameter of type "const wchar_t*"
【问题讨论】:
请在问题中添加您对char
和wchar
之间区别的理解。
在我看来,第一个函数假定 unicode 已启用,而第二个函数假定未启用。
It’s okay to be contrary, but you need to be consistently contrary: Going against the ambient character set。除此之外,我很难理解 “在流程上画线” 应该是什么意思。
对不起,我的意思是我正在读取进程的内存并使用来自该进程的信息使用 GDI/GDI+ 在我的屏幕上画线。并不是真的要借鉴这个过程:D
如果让这两个函数都使用 UNICODE 会有问题吗?我的意思是使用uintptr_t GetModuleBaseAddress(DWORD dwPid, const wchar_t* moduleName)
并将if (!strcmp(ModuleEntry32.szModule, (LPSTR)moduleName))
更改为if (!_wcsicmp(ModuleEntry32.szModule, moduleName))
【参考方案1】:
首先,您的GetProcId()
有问题。它正在泄漏快照HANDLE
,实际上并不是return
'ing 进程ID。
话虽这么说-
您将char
/wchar_t
字符串与TCHAR
API 混合在一起,而这并不意味着它们应该混合在一起。
当UNICODE
被定义时,TCHAR
映射到wchar_t
,PROCESSENTRY32
映射到PROCESSENTRY32W
,Process32First()
映射到Process32FirstW()
等等。
否则,当UNICODE
未定义时,TCHAR
映射到char
,PROCESSENTRY32
映射到PROCESSENTRY32A
,Process32First()
映射到Process32FirstA()
等等。
所以,如果你想使用基于TCHAR
的Win32 API函数,你需要使用基于TCHAR
的字符串和基于TCHAR
的字符串比较(即_tcsicmp()
),例如:
DWORD GetProcId(const TCHAR* procName)
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
do
if (!_tcsicmp(procEntry.szExeFile, procName))
procId = procEntry.th32ProcessID;
break;
while (Process32Next(hSnap, &procEntry));
CloseHandle(hSnap);
return procId;
uintptr_t GetModuleBaseAddress(DWORD dwPid, const TCHAR* moduleName)
uintptr_t dwBase = 0;
do
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwPid);
if (hSnapshot == INVALID_HANDLE_VALUE) continue;
MODULEENTRY32 ModuleEntry32;
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &ModuleEntry32))
do
if (!_tcsicmp(ModuleEntry32.szModule, moduleName))
dwBase = (DWORD)ModuleEntry32.modBaseAddr;
break;
while (Module32Next(hSnapshot, &ModuleEntry32));
CloseHandle(hSnapshot);
while (!dwBase);
return dwBase;
否则,当使用显式char
/wchar_t
字符串时,需要直接使用Unicode/ANSI API,例如:
DWORD GetProcId(const wchar_t* procName)
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
PROCESSENTRY32W procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32FirstW(hSnap, &procEntry))
do
if (!_wcsicmp(procEntry.szExeFile, procName))
procId = procEntry.th32ProcessID;
break;
while (Process32NextW(hSnap, &procEntry));
CloseHandle(hSnap);
return procId;
uintptr_t GetModuleBaseAddress(DWORD dwPid, const char* moduleName)
uintptr_t dwBase = 0;
do
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwPid);
if (hSnapshot == INVALID_HANDLE_VALUE) continue;
MODULEENTRY32A ModuleEntry32;
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32FirstA(hSnapshot, &ModuleEntry32))
do
if (!strcmp(ModuleEntry32.szModule, moduleName))
dwBase = (DWORD)ModuleEntry32.modBaseAddr;
break;
while (Module32NextA(hSnapshot, &ModuleEntry32));
CloseHandle(hSnapshot);
while (!dwBase);
return dwBase;
【讨论】:
以上是关于E0167 “CHAR *”类型的参数与“const wchar_t *”类型的参数不兼容的主要内容,如果未能解决你的问题,请参考以下文章
“char *”类型的参数与“LPWSTR”类型的参数不兼容
“const char *”类型的参数与“Person”类型的参数不兼容
无法在 git bash 终端中使用 char[] PASSWORD =cons.read Password 运行密码屏蔽
深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**cons(示例