我正在使用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上对此进行测试。它可以在使用setlocale(LC_ALL, "en_US.UTF-8")
的Linux上运行,但是在macOS上则无法运行。
结果不包含转换后的字符串,它是原始字符串“ Test String”。我可能会缺少什么?有什么方法可以调试dgettext?
示例项目:https://mega.nz/file/uBATVKKA#O57nnKDHRELEY8m7U_dmC1OZLiK490sqgvoDRnT7wWY
在Linux上使用strace
进行了进一步调查后,尽管setlocale(LC_ALL, "en_US.utf8")
有效,但是setlocale(LC_ALL, "en_US")
无效– strace
的输出包括使用{{1}时不存在的这些行}:
en_US.utf8
Linux似乎正在寻找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)
中使用的默认编码,但是该文件不存在(Ubuntu 20.04.1)
编辑:按照Guido Flohr的建议运行LC_IDENTIFICATION
后,程序将按预期运行。
在macOS 10.15.7(19H2)上使用sudo locale-gen en_US
进行了进一步调查之后,dtruss
调用是针对open
目录(我的默认系统语言)的,该目录不存在,并且en_GB
仅在默认语言设置为en_US
的情况下有效,即English (US)
看起来实际上不能更改语言环境,即使它返回传递给它的语言环境也是如此。这似乎是一个错误?我想我会向苹果报告。
编辑:似乎setlocale
被忽略,而赞成macOS中的setlocale
环境变量(通过Homebrew安装的LANG
)。在gettext
之前添加setenv((char *)"LANG=en_US");
会加载正确的邮件文件,而bindtextdomain
将按预期返回翻译。
答案 0 :(得分:1)
您的代码正确,并且可以在en_US
和en_US.UTF-8
的Mac OS和linux系统上使用。因此,除了您通常应该在调用""
时使用本地语言环境setlocale()
之外,您什么都不会丢失,但是您可能知道自己:
setlocale(LC_ALL, "");
因此,我只能回答如何调试问题的问题。
基本上有两件事可能出错:
首先,您使用setlocale()
选择的语言环境在系统上不可用。通过输出setlocale(LC_ALL, selected_locale)
的返回值可以很容易地检查出它。在测试项目中,您已经做到了。如果所选区域设置不可用,对setlocale()
的调用将返回NULL
。
第二个可能出错的地方是找不到翻译目录。最好在GNU / Linux上使用strace
或在Mac OS上使用dtruss
进行调试:
$ sudo dtruss ./dgettextexample
只需跟踪您的程序正在尝试open()
的文件,以提示问题所在。
答案 1 :(得分:0)
由于可能有多种原因,因此GNU gettext常见问题解答https://www.gnu.org/software/gettext/FAQ.html#integrating_noop包含确定环境中原因的方法。