【问题标题】:C++: How to localize an already-written programC++:如何本地化已经编写好的程序
【发布时间】:2009-09-14 01:36:01
【问题描述】:

我想本地化我已经编写的程序。它相当大(几乎 50k 行),理想情况下,我想要一个允许我(程序员)做尽可能少的工作的系统,并且不需要对程序 - 如果可能的话,根本没有。

我查看了 gettext() 并非常喜欢它,但我不清楚它如何翻译诸如此类的字符串:

const char *Colors[] = {
 { "Red" },
 { "Blue" },
 { "Yellow" },
 ....
};

这在我的程序中非常很常见。这里用 gettext("Red") 替换 "Red" 显然是行不通的。

所以我想我会做类似的事情,OutputFunction(gettext(Colors[Id])),但是我怎样才能获得要本地化的字符串列表呢?我怀疑任何程序都足够聪明,能够从本地化列表中静态地获取“红色”、“蓝色”、“黄色”。

由于它基本上是一个服务器,因此无需重新编译就无需更改语言(我可以为每种支持的语言编译它而没有任何重大问题或烦恼),我想到了 C++0x 的 constexpr,它是完美的!它可以在数组/等中工作,我很容易在编译时获得一个要本地化的字符串列表。太糟糕了,还没有编译器实现它。

将所有字符串更改为 ID 不是一种选择,因为这需要我做大量工作,尤其是为每个新字符串创建一个新 ID 会非常烦人。这同样适用于将上述所有数组转换为其他数组。

那么,有什么想法吗? :/

【问题讨论】:

  • 并不是说这对您有帮助,但顺便说一句,即使constexpr 可用,我怀疑它会对您有所帮助。 constexpr 仅在函数本身可以在编译时评估时才有效,因此如果您修改的 gettext 是基于打开和读取本地化文件,那么您将无法使其成为 constexpr 无论如何(因为打开 &无法在编译时读取文件)。鉴于大多数此类系统都是以这种方式为基础的,我怀疑constexpr 是否真的会有那么大的帮助。

标签: c++ localization gettext


【解决方案1】:

对于您的具体示例,我可能会尝试以下操作:

// presumably globals
const char *Colors_en[] = {
 { "Red" },
 { "Blue" },
 { "Yellow" },
 ....
};
const char *Colors[] = {0};

// in main()
gettextarray(Colors_en, Colors, sizeof(Colors_en) / sizeof(char*));

gettextarray 在每个输入上调用 gettext 并写入一个输出。我认为它可以作为对 std::transform 的调用来实现。你可以通过一些模板技巧来避免 size 参数。

另一个选项是在任何颜色字符串即将被使用(显示,或附加到字符串以进行显示)的位置调用 gettext。这意味着更改更多代码,但不需要 main() 在执行任何可能使用它们的操作之前翻译程序中的每组字符串。

如果您不想在 main 中进行工作,您可以在使用字符串的代码中进行,如下所示:

if (Colors[0] == 0)
  gettextarray(Colors_en, Colors, sizeof(Colors_en) / sizeof(char*));

或者,如果您的应用是多线程的,请考虑 pthread_once 或您使用的线程 API 中的等效项。

【讨论】:

    【解决方案2】:

    在玩了很多 gettext() 和 xgettext 之后,我想我自己找到了一种方法(对不起,我不喜欢你的方法。必须有数百个这样的数组,我必须导入所有它们在 main() 中,这是很多外部和很多额外的工作:/)。

    无论如何,这就是我认为理论上可以做到的方式(我还没有尝试实际翻译,但我不明白为什么它不起作用)

    两个#define:

    #define _ gettext
    #define __(x) x
    

    然后你使用 _ 来实际翻译,使用 __ 简单地将字符串标记为“待翻译”:

    const char *Colors[] = {
     { __("Red") },
     { __("Blue") },
     { __("Yellow") },
     ....
    };
    
    void PrintColor(int id) {
        cout << _("The color is: ") << _(Colors[id]);
    }
    

    然后你运行:

    xgettext -k_ -k__ *.cpp
    

    你会得到以下 .po 文件:

    #: test.cpp:2
    msgid "Red"
    msgstr ""
    
    #: test.cpp:3
    msgid "Blue"
    msgstr ""
    
    #: test.cpp:4
    msgid "Yellow"
    msgstr ""
    
    #: test.cpp:9
    msgid "The color is: "
    msgstr ""
    

    因此,您使用 __(或任何其他名称,并不重要)作为“虚拟函数”,只是让 xgettext 知道字符串需要翻译,而 _ 实际上调用 gettext()。

    如果你用一个字符串调用_,那么这个字符串也将被标记为待翻译,如果你用一个变量、数组调用它,那么它似乎被xgettext简单地忽略了。

    太棒了!现在我所要做的就是浏览 5 万亿个文件并在周围添加下划线,就像我是一只猴子一样:/

    【讨论】:

      猜你喜欢
      • 2020-12-06
      • 2010-09-17
      • 2011-03-17
      • 2010-10-24
      • 2018-11-23
      • 2019-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多