如何在g++中“使用Unicode字符集”?

4

我正在编写一个C++程序,尝试使用Windows的WriteProcessMemory()函数。为此,我需要一个获取目标进程ID的函数。我可以使用以下函数来实现:

#pragma once
#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>

//get process id from executable name using tlhelp32snapshot
DWORD GetProcID(wchar_t *exeName){
    PROCESSENTRY32 procEntry = {0};
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (!hSnapshot) {
        return 0;
    }
    procEntry.dwSize = sizeof(procEntry);
    if (!Process32First(hSnapshot, &procEntry)) {
        return 0;
    }
    do {
        if (!wcscmp(procEntry.szExeFile, exeName)) {
            CloseHandle(hSnapshot);
            return procEntry.th32ProcessID;
        }
    } while (Process32Next(hSnapshot, &procEntry));
    CloseHandle(hSnapshot);
    return 0;
}

//main function
int main() {
    using namespace std;

    cout << "some output" << endl;

    return 0;
}

如果我将字符集设置为Unicode,则可以使用Visual Studio进行编译,但是当我尝试使用g++时,会出现转换错误。
g++ -std=c++17 write.cpp
write.cpp:1:9: warning: #pragma once in main file
 #pragma once
         ^
write.cpp: In function 'DWORD GetProcID(wchar_t*)':
write.cpp:21:43: error: cannot convert 'CHAR* {aka char*}' to 'const wchar_t*' for argument '1' to 'int wcscmp(const wchar_t*, const wchar_t*)'
   if (!wcscmp(procEntry.szExeFile, exeName)) {
                                           ^
write.cpp: In function 'MODULEENTRY32 GetModule(DWORD, wchar_t*)':
write.cpp:40:46: error: cannot convert 'char*' to 'const wchar_t*' for argument '1' to 'int wcscmp(const wchar_t*, const wchar_t*)'
     if (!wcscmp(modEntry.szModule, moduleName)) {
                                              ^

我可以使用以下参数在cl中编译:

-我能够使用以下参数在cl中进行编译:

cl /EHsc /D UNICODE write.cpp

这里的/D UNICODE与在Visual Studio中打开项目属性,将Character Set设置为Use Unicode Character Set相同。

是否有一种像cl那样强制使用g ++中的unicode的选项?


3
是的,g++有-DUNICODE参数。或者你可以在代码中直接使用#define UNICODE。(此外我会移除#pragma once,它不是头文件) - Sandburg
嘿,非常感谢。我之前使用了#define UNICODE,但它没有起作用,所以我将其删除了,但是我尝试了 -DUNICODE,它确实起作用了。非常感谢。 - jumpindonuts
2
你应该使用 W 相关的东西:PROCESSENTRY32W 等等。此外,如果在第一个返回语句处返回,此函数可能会泄漏资源。 - user7860670
3
如果您正在使用mingw-w64,可以使用"-municode"开关,并定义UNICODE来链接正确版本的main等文件。 - M.M
2个回答

2
cl(Microsoft C/C++编译器)和g++(Gnu C++编译器)在某些参数上具有非常相似的语法。它们之间的差异更多是Dos / Shell(斜杠 vs 破折号)之间的常规差异。
g++中,等效于/DMY_IDENTIFIERcl)的是:
-DMY_IDENTIFER

在您的情况下,这意味着:-DUNICODE。完整的编译命令行应该如下:
g++ -DUNICODE -std=c++17 write.cpp

2
正确的做法是使用编译器开关-municode,它定义了您需要的一切,并链接到正确的CRT文件以为您提供适当的_wmain定义。在古老的MinGW上不可用,因此您需要MinGW-w64工具链。很可能您已经在使用它了。如果不是这种情况,您可以从这里下载安装程序。

你让我对编译器中一个我错过的东西有了新的认识。现在,我将总是寻找是否存在“-m”选项与我的工作相关。 - Sandburg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接