java gnu gettext_使用GNUgettext实现本地化语言支持

本文介绍了如何使用GNU Gettext工具在Java应用程序中实现本地化语言支持。通过一步步讲解,包括源代码修改、提取可翻译字符串、翻译过程、消息类别创建以及最终的编译和运行,展示了如何将程序从英文版本转化为Oriya语言。主要涉及的工具有xgettext、msginit、msgfmt,以及对gettext、bindtextdomain和textdomain函数的使用。
摘要由CSDN通过智能技术生成

为了便于操作,不必花费太多时间去阅读本文,我在最后简单地列出了步骤,如果不想看文章细节,就跳到最后,照着做就行。

这篇文章是我翻译的,原作者和题目如下:

A tutorial on Native Language Support using GNU gettext

G. Mohanty

Revision 0.3: 24 July 2004

参考网址如下:

使用GNUgettext实现本地化语言支持

摘要

这里介绍如何利用GNU的gettext工具实现本地语言的支持。 虽然,这篇文章讲解将要支持的语言是Oriya,但是文章中介绍的方法是通用的。同样,虽然这里使用的平台是Linux,但是其他任何系统如果也使用GNU gettext 应该是同样的工作原理。

我们一步一步地来讲解怎样使一个程序打印在屏幕上的消息成为Oriya的而不是English的;从编程序的角度开始,然后以用户使用的角度结束。有些讲解也涉及到了如何进行翻译。

简介

当前,无论是商业还是免费软件都是英文的,并用英文做为文档。直到现在,为使其它非英语语言用户也能够进行交互所做的工作仍然不足,所以这对非英语语言的国家很不利。然而,随着GNU gettext工具的发行,这种状况大大改善了,现在几乎所有的GNU程序是在一个特定框架下面编写的,在这个框架下,可以很容易把英文的程序消息翻译成其它语言。如果能够翻译,那么用户可以在程序运行的时候设置语言选项和程序进行交互。gettext用一种非常优秀的方法解决了这个看起来非常困难的问题,这个方法简化了程序员和翻译者的工作,并且更重要的是它允许程序员和翻译者独立的工作。

这篇文章描述了如何在系统下利用GNUgettext工具来支持本地化语言。本文例子中实际使用的是0.12.1版本,同时,它也适用于其它版本的gettext。另一套系统,在X/Open Portability Guide中描述的叫做called catgets,也正在被使用,但是我们在这里不对其进行讨论。

一个简单的例子

我们的第一个使用gettext的例子是传统的helloworld程序,它只包含了一个函数用来打印“Hello World”信息到终端上。这个程序的国际化版本保存为hello.c如下:

01    #include

02    #include

03    #include

04    #include

05    int main(void)

06    {

07      setlocale( LC_ALL, "" );

08      bindtextdomain( "hello", "/usr/share/locale" );

09      textdomain( "hello" );

10      printf( gettext( "Hello, world!\n" ) );

11      exit(0);

12    }

在实际中,我们应该检查函数的返回值以捕获各种错误,但为清晰起见这里忽略了这些处理。编译的时候使用我们常用的命令:gcc -o hello hello.c。这个程序本来是应该链接到GNU libintl库的,但是做为GNU C库的一个组成部分,如果你是在Linux或者其它使用glibc的系统中,这一步会被自动进行。

程序员的角度

当hello可执行文件在默认的情况下运行的时候,(通常是C 情况?什么意思?),它在终端打印出"Hello,world!"字样。另外,它还会做一些初始的设置工作。程序员唯一需要做的工作就是把所有将要打印的字符替换为gettext(字符串),也就是说,把字符做为一个参数传递给gettext函数。有些时候为了简便,我们可以把函数定义为一个cpp宏,例如,可以在源代码的开头加上一句:

#define _(STRING) gettext(STRING)

然后,就可以使用_(字符串)来替代gettext(字符串)了。

下面,我们来一行一行地对这个程序进行分析。

locale.h文件定义了用来保存多语言化信息的c数据结构,并且setlocale函数也需要这个文件。

libintl.h文件声明了GNU text 工具函数,这里的bindtextdomain,gettext,和textdomain函数就需要用到这个文件。

第7行的setlocale()调用,把LC_ALL做为它的第一个参数,把空字符串做为它的第二个参数,这样把程序当前的所有多语言 相关设置为用户定义的每一个环境变量。也就是说,这个程序的多语言相关设置被初始化为和用户相匹配的环境。关于更多的细节信息,我们可以参见"man setlocale"手册说明。

第8行的函数bindtextdomain设置了?为给定的消息域的消息类别?的基本目录。消息域是一个翻译的消息的集合,每一个软件包一般都有它自己的域。在这里,我们使用"hello"做为我们程序的消息域。这里的第2个参数(/usr/share/locale)是消息类别的默认系统路径,我们将要把消息类别放在默认的系统路径中。因此我们可以在这里不用调用bindtextdomain函数?,这个函数仅在消息类别没有被安装在标准路径的时候才会有用,例如一个打包的软件发行可能会把类别放在它主目录下面的po/目录中,我们可以参见"man bindtextdomain"来了解更为详细的信息。

第9行的textdomain函数调用把当前程序的消息域设置为"hello",也就是我们这个程序使用的名字。我们可以参见"man textdomain"来了解更为详细的信息。

最后,我们把第10行的:

printf( "Hello, world!\n" );

替换成了:

printf( gettext( "Hello, world!\n" ) );

(如果你不熟悉C语言,字符串末尾的\n会在输出的末尾打印一个新行)对于所有可以翻译的字符串,这个简单的修改实现了翻译者和程序员之间的工作相互独立。如果一个包第一次使用GNUgettext或者升级到新版本的gettext,gettextize减轻了减轻了程序员的工作。

提取可以翻译的字符串

现在应该从程序的源代码中提取将要翻译的字符串了。这个工作是利用xgettext完成的,如下:

xgettext -d hello -s -o hello.pot hello.c

这里,会处理hello.c中的源代码,并且把输出保存到一个hello.pot文件中(这个在选项-o已经指明了的)。-s选项告诉xgettext产生排好序的输出。程序中的消息域使用-d选项的参数来指定,这个消息域应该和textdomain调用中指定的消息域相匹配。(在源代码中的第9行)。其它关于如何使用gettext的细节问题可以参见“man gettext”。

.pot文件(portable object template)是把程序中相关信息翻译成其它语言得基础。开始翻译之前,可以把hello.pot拷贝一份副本oriya.po(这样保留原来的模板文件便于今后翻译成其它的语言);然而更好的方法是使用msginit程序,这个程序还可以正确地设置一些默认的值。

msginit -l or_IN -o oriya.po -i hello.pot

这里,-l 选项定义了语言(这里需要在你的系统中安装Oriya语言),-i 选项和-o选项分别定义了输入和输出文件。这里,oriy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值