【问题标题】:E0167 argument of type "CHAR *" is incompatible with parameter of type "const wchar_t *"E0167 “CHAR *”类型的参数与“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)) {

标签: c++ winapi


【解决方案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;
}

【讨论】:

    猜你喜欢
    • 2020-12-02
    • 1970-01-01
    • 2019-12-16
    • 2016-05-19
    • 2020-01-20
    • 1970-01-01
    • 2021-08-06
    • 2020-11-19
    • 2019-10-31
    相关资源
    最近更新 更多