在 glib 中强制使用 UTF-8 编码 "g_print()"

Force UTF-8 encoding in glib's "g_print()"

小问题:有没有办法强制 glib 的 g_print() 使用 UTF-8 编码?


我遇到的问题是g_print()seems to do character set conversion based on the return value of g_get_charset()。现在文档不幸提到

On Windows the character set returned by this function is the so-called system default ANSI code-page.

然而现在现代控制台可用:MSYS 控制台通常默认支持(并使用)UTF-8,甚至默认 Windows 控制台也可以设置为使用 UTF-8 编码。

现在看来 Windows 终于赶上来了,毕竟 glib 将我限制为 255 个字符的代码页???
我只是将我的代码切换为纯 printf 但不幸的是 g_print 在 glib 和 gtk 库以及它们的 C++ 绑定 glibmm 和 gtkmm 内部的许多位置被调用,我显然没有容易的可能性除了自己修补和编译 glib 之外,我可以改变任何事情,所以我真的希望有一个解决方案。


注:刚看到g_print()定义中调用local_glib_print_func()的部分。 Aynbody 知道这是怎么回事,我是否可以利用它来达到我的目的?

嗯,其实我给了自己正确的提示:

在调查我的问题中的 Note 时,我发现了 g_set_print_handler 函数,它允许创建一个任意处理程序来替换默认机制并规避字符转换。

下面的最小打印处理程序让我打印到控制台 g_print() 避免任何不需要的字符集转换:

#include <cstdio>
#include <glib.h>

void g_print_no_convert(const gchar *buf)
{
    fputs(buf, stdout);
}

int main (int argc, char **argv)
{
    g_set_print_handler(g_print_no_convert);
    g_print("UTF-8 string");

    return 0;
}

注意:编写 UTF-8 字符串显然只有在您的控制台编码实际上是 UTF-8 时才有效。


在 Windows 上,您可以通过执行命令 chcp 65001 手动或使用以下 API 函数

以编程方式将控制台的编码设置为 UTF-8
#include <windows.h>

// temporarily switch console encoding to UTF8
const unsigned int initial_cp = GetConsoleOutputCP();
SetConsoleOutputCP(CP_UTF8);

{...} // printing

// switch back to initial console encoding
SetConsoleOutputCP(initial_cp);

这种方法可以轻松地将 UTF-8 字符串打印到 Windows 控制台(使用默认控制台以及 Windows 10 上的 MSYS2 终端进行测试)。