【发布时间】:2020-10-28 12:15:10
【问题描述】:
我使用 gettext/libintl 如下:
setlocale(LC_ALL, "en_US");
char * result = bindtextdomain("MyApp", "/absolute/path/to/locale/dir");
assert(result);
result = dgettext("MyApp", "Test String");
在/absolute/path/to/locale/dir 我有翻译文件在en_US/LC_MESSAGES/MyApp.mo。
我正在 macOS 上对此进行测试。它在 linux 上使用 setlocale(LC_ALL, "en_US.UTF-8") 工作,但这在 macOS 上不起作用。
结果不包含翻译后的字符串,它是原始字符串“测试字符串”。我可能会错过什么?有没有办法调试 dgettext?
示例项目:https://mega.nz/file/uBATVKKA#O57nnKDHRELEY8m7U_dmC1OZLiK490sqgvoDRnT7wWY
在 Linux 上使用 strace 进行进一步调查后,虽然 setlocale(LC_ALL, "en_US.utf8") 有效,但 setlocale(LC_ALL, "en_US") 无效 - strace 输出包括使用 en_US.utf8 时不存在的这些行:
openat(AT_FDCWD, "/usr/lib/locale/en_US/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/locale/en/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
Linux 似乎正在寻找要在 LC_IDENTIFICATION 中使用的默认编码,但该文件不存在 (Ubuntu 20.04.1)
编辑:按照Guido Flohr 的建议运行sudo locale-gen en_US 后,程序按预期运行。
在 macOS 10.15.7 (19H2) 上使用 dtruss 进行进一步调查后,open 调用是针对不存在的 en_GB 目录(我的默认系统语言),并且 en_US 仅在以下情况下才有效默认语言设置为English (US),即看起来setlocale实际上无法更改语言环境,即使它返回传递给它的语言环境。这似乎是一个错误?我想我会向 Apple 报告。
编辑:似乎 setlocale 被忽略,而在 macos 中使用 LANG 环境变量(gettext 通过 Homebrew 安装)。在bindtextdomain 加载正确的消息文件之前添加setenv((char *)"LANG=en_US");,dgettext 按预期返回翻译。
【问题讨论】:
-
setlocale(LC_ALL, "en_US")在您的 linux 系统上失败(返回null)。所以这是一个 glibc 问题。你能检查locale -a的输出吗?您是否尝试使用sudo locale-gen en_US安装语言环境en_US? -
Ubuntu 设置的语言设置为
English (United States)。但是,locale -a仅返回en_US.utf8(以及其他语言)。在按照建议运行sudo locale-gen en_US后,出现了en_US和en_US.iso88591。然后程序使用setlocale(LC_ALL, "en_US")按预期运行。这样Linux就解决了,谢谢 -
现在 macOS 也解决了(有点)。感谢您的帮助。
标签: c internationalization gettext