我想将项目保留在多字节上,而不是将其切换为Unicode。我在尝试使我的类型按如下方式协同工作时遇到一些错误(VS2019设置为bybye):
原始错误是:“ char *”类型的参数与以下行的“ const wchar_t *”类型不兼容:
if (!wcscmp(ModuleEntry.szModule, ModuleName)
ModuleEntry的类型为MODULEENTRY32
如果我将ModuleEntry的类型更改为MODULEENTRY32W
,则会出现以下错误:
参数类型“ MODULEENTRY32W”与类型“ LPMODULEENTRY32”不兼容。
完整功能供您参考:
DWORD GetModuleBaseAddress(const wchar_t* ModuleName, DWORD ProcessId) {
MODULEENTRY32 ModuleEntry = { 0 };
HANDLE SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessId);
if (!SnapShot)
return NULL;
ModuleEntry.dwSize = sizeof(ModuleEntry);
if (!Module32First(SnapShot, &ModuleEntry))
return NULL;
do {
if (!wcscmp(ModuleEntry.szModule, ModuleName)) {
CloseHandle(SnapShot);
return (DWORD)ModuleEntry.modBaseAddr;
}
} while (Module32Next(SnapShot, &ModuleEntry));
CloseHandle(SnapShot);
return NULL;
}
谢谢。
答案 0 :(得分:2)
首先,如果SnapShot
失败,则会泄漏Module32First()
句柄。
第二,您使用的是基于TCHAR
的Module32 API版本,但是您正在传入wchar_t
Unicode数据以将枚举的模块数据进行比较。您已将项目设置为MultiByte,这意味着TCHAR
映射到char
,而基于TCHAR
的API映射到ANSI API。
因此,您实际上是在调用Module32 API的 ANSI 版本,即MODULEENTRY32
映射到MODULEENTRY32A
和Module32First()
/ Module32Next()
映射到Module32FirstA()
/ Module32NextA()
。
您不能将char
数据传递到wcscmp()
,也不能将wchar_t
数据传递给strcmp()
。因此,如果继续使用ANSI API,则必须在运行时在一个方向或另一个方向上执行数据转换,转换为:
将char
模块数据通过wchar_t
转换为MultiByteToWieChar()
将wchar_t
比较数据通过char
WideCharToMultiByte()
然后您才能使用适当的函数来比较两个数据。
由于要传递wchar_t
数据以进行比较,因此应明确地调用Module32 API的 Unicode 版本,而不是TCHAR
版。您不必将整个项目都设置为Unicode即可使用Unicode API,例如:
void* GetModuleBaseAddress(const wchar_t* ModuleName, DWORD ProcessId)
{
HANDLE SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessId);
if (SnapShot)
{
MODULEENTRY32W ModuleEntry = { 0 };
ModuleEntry.dwSize = sizeof(ModuleEntry);
if (Module32FirstW(SnapShot, &ModuleEntry))
{
do
{
if (wcscmp(ModuleEntry.szModule, ModuleName) == 0)
{
CloseHandle(SnapShot);
return ModuleEntry.modBaseAddr;
}
}
while (Module32NextW(SnapShot, &ModuleEntry));
}
CloseHandle(SnapShot);
}
return NULL;
}