gettext是GNU国际化与本地化(i18n)库,它常被用于编写多语言程序。多数编程语言均已通过字符封装的方式实现了对其的支持。主要相关的函数有:
char*setlocale(intcategory,constchar*locale);
char*bindtextdomain(constchar*domainname,constchar*dirname);
char*textdomain(constchar*domainname);
char*gettext(constchar*msgid);
char*dgettext(constchar*domainname,constchar*msgid);
char*dcgettext(constchar*domainname,constchar*msgid, intcategory);
bindtextdomain()用来设置文本域目录。所谓的文本域文件就是mo文件,mo文件在开发多语言软件中会用到,比如正常打印"helloworld"的英文,为了在中文环境中得到相应显示,我们将这句话翻译为“你好,世界”,然后将这句中文放在一个mo文件中,一般会将该文件放在/usr/share/locale/zh_CN/LC_MESSAGES中。基于性能方面的考虑,mo文件一般会做为二进制文件。
接着,一般会再使用textdomain()函数设置需要使用的文本域(textdomain)。这些文本域之前都是经过bindtextdomain()指定的,再经过textdomain()函数设置后,那么此后gettext库(及其中的相关函数)便能找到相应的mo文件并操作它们。
如果程序需要用到多个mo文件,那么需要使用bindtextdomain()函数多次,然后使用textdomain()来指定当前需要使用哪一个。
下面以一个例子来说明C语言下进行多语言编程。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <locale.h> #include <libintl.h> #define LOCALEDIR "/usr/share/locale/" #define _(string) gettext(string) int main(int argc, char *argv[]) { setlocale (LC_ALL, ""); /* Set the text message domain. */ bindtextdomain ("hello", LOCALEDIR); textdomain ("hello"); printf(_("This is a test!\n")); printf(_("hello world\n")); return 0; }
创建pot文件,pot是PortableObject Template的首字母缩写,与po对应的是mo,mo是MachineObject的首字母缩写。前者意指原始的字符串文件,一般用于给翻译人员去修改的,后者则是与机器相关的,一般是供程序读取。可以手工创建pot文件,也可以通过xgettext从代码中抽取字符串来产生。用xgettext来产生pot文件的命令如下:
xgettext --keyword=_ -o hello.pot hello.c
运行该命令后将产生hello.pot文件,根据此文件产生不同语言的po文件,这里我们产生一个简体中文的po文件:
msginit-l zh_CN.UTF-8 -i hello.pot
将生成的zh_CN.po文件内容相应位置翻译成中文,内容如下:
# Chinese translations forPACKAGE package # PACKAGE 软件包的简体中文翻译. # Copyright (C) 2012 THEPACKAGE'S COPYRIGHT HOLDER # This file is distributedunder the same license as the PACKAGE package. # fuyajun<[email protected]>, 2012. # msgid "" msgstr "" "Project-Id-Version:PACKAGE VERSION\n" "Report-Msgid-Bugs-To:\n" "POT-Creation-Date:2012-01-08 16:18+0800\n" "PO-Revision-Date:2012-01-08 16:19+0800\n" "Last-Translator:fuyajun <[email protected]>\n" "Language-Team:Chinese (simplified)\n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type:text/plain; charset=UTF-8\n" "Content-Transfer-Encoding:8bit\n"
#: hello.c:18 #, c-format msgid "This is atest!\n" msgstr "这是一个测试!\n"
#: hello.c:19 #, c-format msgid "hello world\n" msgstr "你好世界" |
最后,将po文件转换为mo文件,命令如下:
msgfmtzh_CN.po -o hello.mo
将hello.mo文件复制到/usr/share/locale/zh_CN/LC_MESSAGES/目录下。
测试结果如下: