问题描述
这是一些CSGO代码的一部分,我不知道如何解决这个问题;它位于下面显示的代码段的第 8 行:
uintptr_t GetModuleBaseAddress(const char* modName) {
HANDLE hSnap = Createtoolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32,procId);
if (hSnap != INVALID_HANDLE_VALUE) {
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if (Module32First(hSnap,&modEntry)) {
do {
if (!strcmp(modEntry.szModule,modName)) {
CloseHandle(hSnap);
return (uintptr_t)modEntry.modBaseAddr;
}
} while (Module32Next(hSnap,&modEntry));
}
}
}
错误信息:
Argument Type (WCHAR*) is incompatible with parameter of type "const char*)
解决方法
如评论中所述,您的问题在于您的(新)项目为构建设置了“使用 Unicode 字符集”选项,但(旧)代码库期望使用“使用多字节字符集”选项。 (前者对 Windows API 调用和结构中的字符串使用 wchar_t*
类型,而后者使用 char*
类型;这些是不兼容的指针。)
因此,“快速修复”是将项目的构建选项设置为使用“多字节”字符集。在Visual Studio 2019中,在解决方案资源管理器中右键单击项目时,该选项是项目的属性->高级->字符集;早期版本的 Visual Studio 具有常规属性选项卡 IIRC 中的选项。
如果您使用的是其他 IDE,那么您需要“手动”取消定义 UNICODE
宏(这会向编译器发出“Unicode 字符集”正在使用中的信号); #undef UNICODE
行 before 用于系统标题的任何 #include <...>
行都可以使用。
对于大部分(大多数)Windows API,这个问题也可以通过使用显式wchar_t
或char
版本的结构和函数来解决;例如,注释中提到的 GetModuleFileName
函数会解析为 GetModuleFileNameW
或 GetModuleFileNameA
,具体取决于为构建选择的字符集,并且这些调用中使用的结构具有 { {1}} 和 W
版本明确定义。因此,可以通过显式使用这些函数和结构的 A
- 或 A
- 后缀版本来“覆盖”项目设置的默认调用。
但是,不幸的是,在您的特定情况下,W
头文件(及其定义的函数)定义得不是很好:没有显式 TlHelp32.h
-后缀版本,因此您不能像人们希望的那样简单地将 A
和 MODULEENTRY32
引用后缀为 Module32First
。 (对于 Unicode 版本,带有 A
后缀的版本只会覆盖“原始”函数和结构名称,因此这些会丢失到您的代码中。)
因此,无需更改您的代码以始终使用 W
类型(TCHAR
解析为 TCHAR
或 char
,具体取决于字符集选项),您唯一明智的做法是选项是前面提到的快速修复:更改构建设置。