参数类型 (WCHAR*) 与“const char*”类型的参数不兼容

问题描述

这是一些CSGO代码的一部分,我不知道如何解决这个问题;它位于下面显示代码段的第 8 行:

enter image description here

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 UNICODEbefore 用于系统标题的任何 #include <...> 行都可以使用。

对于大部分(大多数)Windows API,这个问题也可以通过使用显式wchar_tchar 版本的结构和函数来解决;例如,注释中提到的 GetModuleFileName 函数会解析为 GetModuleFileNameWGetModuleFileNameA,具体取决于为构建选择的字符集,并且这些调用中使用的结构具有 { {1}} 和 W 版本明确定义。因此,可以通过显式使用这些函数和结构的 A- 或 A- 后缀版本来“覆盖”项目设置的默认调用。

但是,不幸的是,在您的特定情况下,W 头文件(及其定义的函数)定义得不是很好:没有显式 TlHelp32.h-后缀版本,因此您不能像人们希望的那样简单地将 AMODULEENTRY32 引用后缀为 Module32First。 (对于 Unicode 版本,带有 A 后缀的版本只会覆盖“原始”函数和结构名称,因此这些会丢失到您的代码中。)

因此,无需更改您的代码以始终使用 W 类型(TCHAR 解析为 TCHARchar,具体取决于字符集选项),您唯一明智的做法是选项是前面提到的快速修复:更改构建设置。