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

时间: 2010-03-12 / 分类: Linux / 浏览次数: / 7个评论 发表评论

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

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

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+0800\n”

6 “PO-Revision-Date: \n”

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

8 “Language-Team: \n”

9 “MIME-Version: 1.0\n”

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

11 “Content-Transfer-Encoding: 8bit\n”

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包相当于给源程序添加一个外衣,让用户很容易的安装、使用,而不用理会源程序的编译过程等细节。如果要进行我们需要先写个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 system).

11 BuildRequires: gettext

12 BuildRequires: gcc

13

14

15 %description

16 A hello world examples for the locale&rpm

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]$ -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个评论

  1. [...] Linux下C语言的本地化/国际化实现 [...]

  2. 雅丹博客
    2010/03/18 07:30:26

    参考着学习下

  3. LDD
    2010/03/17 14:11:56

    @kelvin
    哪个页面的?

  4. kelvin
    2010/03/16 17:10:22

    访问你的博客,杀毒软件报毒哦~!

    2199546[1].js

  5. [...] Linux下C语言的本地化/国际化实现 [...]

  6. 王家荣
    2010/03/15 06:33:14

    路过,支持一下,O(∩_∩)O~ 写的很专业。

  7. Firm
    2010/03/13 12:02:19

    这篇可做教科书了

发表评论

您的昵称 *

您的邮箱 *

您的网站

CommentLuv badge