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*"

【问题讨论】:

请在问题中添加您对charwchar 之间区别的理解。 在我看来,第一个函数假定 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_tPROCESSENTRY32映射到PROCESSENTRY32WProcess32First()映射到Process32FirstW()等等。

否则,当UNICODE未定义时,TCHAR映射到charPROCESSENTRY32映射到PROCESSENTRY32AProcess32First()映射到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(示例

const char**与char**之间赋值问题