C++ stricmp不';我的代码不起作用

C++ stricmp不';我的代码不起作用,c++,winapi,comparison,data-conversion,C++,Winapi,Comparison,Data Conversion,我正在循环浏览TlHelp32的进程快照,然后将名称与stricmp进行比较,以获得进程句柄。问题是,尽管两个值似乎相同,但它们显然不同,因为它不返回0。我不知道为什么,我也尝试过将进程名写入函数中 HANDLE GetProcessValues(std::string ProcName) { const char* ProcNameChar = ProcName.c_str(); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_S

我正在循环浏览TlHelp32的进程快照,然后将名称与stricmp进行比较,以获得进程句柄。问题是,尽管两个值似乎相同,但它们显然不同,因为它不返回0。我不知道为什么,我也尝试过将进程名写入函数中

HANDLE GetProcessValues(std::string ProcName)
{
   const char* ProcNameChar = ProcName.c_str();
   HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   PROCESSENTRY32 process;
   ZeroMemory(&process, sizeof(process));
   process.dwSize = sizeof(process);
   if (Process32First(snapshot, &process))
   {
       do
       {
           if (_stricmp((char*)process.szExeFile,ProcNameChar)==0)
           {
               HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
               return hProc;
           }
       }while (Process32Next(snapshot,&process));
   }
   return 0;
}
我调试了它以查看值是否合适:

处理
wchar*
数据类型时,使用
\u wcsicmp
进行比较,必要时,将任何涉及的
char*
数据类型转换为
wchar*
等效类型,例如使用CStringW类。协商,并注意使用正确的区域设置。在

中描述了wchar*常量的一个类似问题。问题是您使用的是
TCHAR
版本的
Process32First()
/
Process32Next()
,调试器screnshot清楚地显示您正在为Unicode编译项目,因此
TCHAR
映射到
WCHAR
,因此
process.szExeFile
是一个
WCHAR[]
数组。您错误地将该数组类型转换为
char*
指针。不能直接将Unicode字符串与Ansi字符串进行比较。在比较之前,需要将一个字符串转换为另一个字符串的编码

您还泄漏了
CreateToolhelp32Snapshot()
返回的
句柄

由于将Ansi
std::string
作为输入传递给
GetProcessValues()
函数,最简单的解决方案是使用Ansi版本的
Process32First()
/
Process32Next()
,因此
process.szefile
现在是一个
CHAR[]
数组,因此,无需转换:

HANDLE GetProcessValues(std::string ProcName)
{
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snapshot == INVALID_HANDLE_VALUE)
        return NULL;

    PROCESSENTRY32A process;
    ZeroMemory(&process, sizeof(process));
    process.dwSize = sizeof(process);

    const char* ProcNameChar = ProcName.c_str();
    HANDLE hProc = NULL;

    if (Process32FirstA(snapshot, &process))
    {
        do
        {
            if (_stricmp(process.szExeFile, ProcNameChar) == 0)
            {
                hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
                break;
            }
        }
        while (Process32NextA(snapshot, &process));
    }

    CloseHandle(snapshot);
    return hProc;
}
然而,您确实应该远离使用Ansi API。Windows是一个基于Unicode的操作系统,并且已经存在很长时间了。改用Unicode API:

HANDLE GetProcessValues(std::wstring ProcName)
{
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snapshot == INVALID_HANDLE_VALUE)
        return NULL;

    PROCESSENTRY32W process;
    ZeroMemory(&process, sizeof(process));
    process.dwSize = sizeof(process);

    const wchar_t* ProcNameChar = ProcName.c_str();
    HANDLE hProc = NULL;

    if (Process32FirstW(snapshot, &process))
    {
        do
        {
            if (_wcsicmp(process.szExeFile, ProcNameChar) == 0)
            {
                hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
                break;
            }
        }
        while (Process32NextW(snapshot, &process));
    }

    CloseHandle(snapshot);
    return hProc;
}
如果
ProcName
参数绝对必须是
std::string
,则可以:

  • 使用
    MultiByteToWideChar()
    std::wstring\u convert
    等将
    ProcName
    转换为Unicode,然后将该结果与Unicode API返回的字符串进行比较

  • 使用
    WideCharToMultiByte()
    std::wstring\u convert
    等将Unicode API中的字符串转换为Ansi,然后将这些结果与
    ProcName
    进行比较


  • 为什么在
    \u stricmp
    的第一个参数中强制转换为
    char*
    ?如果是为了让编译器对类型不匹配错误闭嘴,请停止这样做,并为函数提供正确的字符串类型。不要强制转换字符串类型——强制转换不是转换。你对编译器撒了谎,得到的只是甜点,而不是黑客,让你的应用程序成为Unicode。使用
    std::wstring
    而不是
    std::string
    wchar\u t
    而不是
    char
    ,等等。你需要明白你必须停止对编译器撒谎。这就是第1步。问题是你有一个大杂烩的字符串类型,你没有一个连贯的设计,以什么样的实际字符串类型,你的应用程序正在使用。这里是Char,那里是wchar,这里是Unicode函数调用,那里是ANSI函数调用,等等。重点是使用一种且仅使用一种字符串类型,并调用处理这些字符串类型的正确函数。最好是坚持Unicode,因为目前在Windows和Windows时代,很少有MBCS应用程序被创建。<代码> WCHAR */COM>不是C++中的一个完整数据类型。这与C++的
    wchar\u t*
    或Windows SDK的
    wchar*
    相混淆。除此之外,
    CStringW
    大概是一个MFC/ATL类模板。除非您正在编写MFC或ATL代码,否则这不适用(通常不适用于Windows API编程)。Windows API中的转换函数为。一个C++的替代方案是。