C++ stricmp不';我的代码不起作用
我正在循环浏览TlHelp32的进程快照,然后将名称与stricmp进行比较,以获得进程句柄。问题是,尽管两个值似乎相同,但它们显然不同,因为它不返回0。我不知道为什么,我也尝试过将进程名写入函数中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
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()
返回的句柄
由于将Ansistd::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++的替代方案是。