Linux下C语言的本地化/国际化实现

在linux系统下,以c语言程序为例来实现程序的国际化,即让程序根据Linux系统不同的语言环境的不同来显示出对应该语言的文字,即先让c程序支持国际化然后再进行本地化翻译。

Linux上实现这个过程需要用到xgettext和msgfmt这两个工具。

Xgettext 是国际化的工具,用来提取程序中的字符串,生成*.po或是*.pot的文件,

msgfmt是本地化的工具,用来编译翻译后的.po文件为.mo文件,这样系统在启动时候会扫描系统环境提取对应名字的.mo文件中的字符串替代原来的英文,实现本地化。

如我们来做一个简单的rpm包,包文件的目录树如下:

hello.c /*我们用来测试的c语言程序*/

po /zh_CN.po /*放在该包根目录下的po目录。对应于该程序进行的中文翻译*/

第一步、支持国际化的C程序(hello.c)如下:

1 #include <stdio.h>2 #include <libintl.h> // gettext 库支持

3 #include <locale.h> // 本地化locale的翻译支持

4

5 #define _(STRING) gettext(STRING) //为了减少代码量和输入量,用别名_(STRING)替换gettext(STRONG)

6 #define PACKAGE “hello” // 定义软件包的名字为hello

7 #define LOCALEDIR “/usr/share/locale/” //定义系统语言环境的目录,该目录下存放各种国际化的语言,不同系统可能有差异。

8

9

10 int main (int argv, char *argc[] )

11 {

12 setlocale (LC_ALL, “”); //设置locale为系统默认语言环境,gtk程序不需要,因为gtk_init()已经帮我们做了

13 bindtextdomain (PACKAGE, LOCALEDIR); //关联包名称及其对应的国际化翻译语言所在路径

14 textdomain (PACKAGE); //定义.mo文件的名字,省略“.mo”后缀,(可以多个路径下的不同mo文件)

15 printf(_(“Hello, World!n”)); //国际化字符串支持,结合上面的替换,实际应是:printf(gettext(“Hello, World!n”));

16 printf(_(“This is a example of locale&rpm @ Neoshine Desktop 5!n”));

17 return 0;

18 }

第二步、提取待翻译po并进行本地化

先用下面的命令提取出c程序中需要进行本地化的语言文件。

[Lee@leedd.com hello]$  xgettext  -k keyword=_  hello.c  -o  hello.pot

再用poedit或是vim翻译hello.pot中对应英文为中文并另存为zh_CN.po ,作为中文本地化的翻译文件。

如下面翻译后的zh_CN.po文件的内容:

1 msgid “”2 msgstr “”

3 “Project-Id-Version: n”

4 “Report-Msgid-Bugs-To: n”

5 “POT-Creation-Date: 2010-03-11 11:52+0800n”

6 “PO-Revision-Date: n”

7 “Last-Translator: Leedd <iam@Leedd.com>n”

8 “Language-Team: n”

9 “MIME-Version: 1.0n”

10 “Content-Type: text/plain; charset=UTF-8n”

11 “Content-Transfer-Encoding: 8bitn”

12

13 #: hello.c:15

14 #, c-format

15 msgid “Hello, World!n”

16 msgstr “你好,世界!n”

17

18 #: hello.c:16

19 #, c-format

20 msgid “This is a example of locale&rpm @ Leedd.com !n”

21 msgstr “这是在沉思小屋下的关于”本地化”和”rpm打包”的测试!n”

第三步、把翻译后的文件打包

制作rpm包相当于给源程序添加一个外衣,让用户很容易的安装、使用,而不用理会源程序的编译过程等细节。如果要进行rpmbuild我们需要先写个SPEC文件,如下:

Neoshine-hello-wrold.spec文件内容

1 Name: neoshine-hello-world

2 Version: 5.0

3 Release: 1

4 License: GPL+

5 Group: Applications/System

6 URL: http://leedd.com

7 Source0: %{name}-%{version}.tar.bz2

8 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root

9

10 Summary: A applet for Neoshine Desktop (or the other similar Linux system).

11 BuildRequires: gettext

12 BuildRequires: gcc

13

14

15 %description

16 A hello world examples for the localerpm

17

18 %prep

19 %setup -q

20

21 ##,%build

22

23 %install

24

25 mkdir -p ${RPM_BUILD_ROOT}/usr/share/locale/zh_CN/LC_MESSAGES

26 mkdir -p ${RPM_BUILD_ROOT}/var/tmp/hello

27 xgettext -k –keyword=_ hello.c -o po/hello.pot

28 pushd ./po

29 msgmerge zh_CN.po hello.pot

30 msgfmt zh_CN.po -o hello.mo

31 cp hello.mo ${RPM_BUILD_ROOT}/usr/share/locale/zh_CN/LC_MESSAGES

32 popd

33

34 gcc hello.c -o ${RPM_BUILD_ROOT}/var/tmp/hello/hello.out

35

36 %clean

37 rm -rf $RPM_BUILD_ROOT

38

39 %files

40 %defattr(-,root,root)

41 /var/tmp/hello/*

42 /usr/share/locale/zh_CN/LC_MESSAGES

43

44 %changelog

45 * Thu Mar 11 2010 Leedd <iam@leedd.com> 5.0-1

46 – Inital

已经有了源文件和SPEC文件后,需要把他们分别放在rpmbuild目录下对应的SOURCESSPECS目录中,然后打包:

[Lee@leedd.com SPECS]$ rpmbuild -bs neoshine-hello-world.spec Wrote: /home/Lee/rpmbuild/SRPMS/neoshine-hello-world-5.0-1.src.rpm

[Lee@leedd.com SPECS]$ mock -r neoshine-5-i686 rebuild   /home/Lee/rpmbuild/SRPMS/neoshine-hello-world-5.0-1.src.rpm

本文用到的源程序:
 http://leedd.com/docs/linux/hello-world-c/ 
 SOURCES源文件:neoshine-hello-world-5.0.tar.bz2
 SPEC文件:  neoshine-hello-world.spec
 编译后的源码包:neoshine-hello-world-5.0-1.src.rpm

参考文章:

[1] Hello World http://zh.wikipedia.org/wiki/Hello_World#C

[2] Linux 国际化编程 http://riuliyu.blog126.fc2.com/blog-entry-20.html

[3] 认识下linux下程序的国际化(C语言实例)

http://swinging-breeze.blogspot.com/2009/05/linuxc.html (已经被墙)

Google的缓存: http://203.208.39.132/search?q=cache:E-Os3g0yHjsJ:swinging-breeze.blogspot.com/2009/05/linuxc.html+hello+world+%E5%9B%BD%E9%99%85%E5%8C%96+c%E8%AF%AD%E8%A8%80&cd=1&hl=zh-CN&ct=clnk&gl=cn&st_usg=ALhdy2_j1VcwccRlk394Xz6n81ZnDCvbuQ

7 thoughts on “Linux下C语言的本地化/国际化实现

  1. Pingback: Linux本地化翻译中的po或pot格式介绍 | 沉思小屋

  2. Pingback: 今天Google pr更新 | 沉思小屋

Comments are closed.