k8凯发一触即发|Home

135-9299-6491
 
你会用m17n对各国语言间代码移植转换吗?
日期:12-07 浏览次数:10

 你会用m17n对各国语言间□□代码移植转换◣吗?

  为了让 Linuxreg; 应用程序在全□□□□世界范围都可□□以使用,而不会在西方□□□语言与世界上□□□□其他语言之间□□产生任何区别,我们应该发行□□□一些本地化后□□的版本,它们可以输入、存储、提取或呈现 任何语言,而不管这些语□□□言是多么复杂。多语言库,或称为 m17n,为类 UNIXreg; 平台上的所有◢语言提供了一□□□个国际化解决□□方案。

  在很短的时间□□□□之内 —— 总共还不到 20 年 —— 个人计算机已●经成为我们工□□作和生活中的□□一种必需设备。受到半导体和□□□处理器快速发★展的推动,大量的供应商●使得计算机的□□□价格一落千丈,Internet 也已经在全球○广为分布,个人计算机现□□□□在已经不再是□□□一种高品质品,而是一种常见□□□的家用电器了。

  实际上,在很多富裕的□□□国家(例如美国、日本、英国),每两个家庭就□□会拥有一台计□□算机,并且会使用宽□□□带服务。就全世界来看,虽然家庭收入□□可能会有 很大的不同,但是个人计算□□机都很容易购●买了,即使在马尔代□□□夫,我们也很容易□□□购买到笔记本。另外,如果我们碰巧◇说的是 Dhivehi 方言(马尔代夫的一◇种方言),微软也为我们□□提供了一个这◤种版本的 Microsoftreg; Windowsreg; XP 操作系统。

  就全球广泛接□□□□受的个人计算□□机来说,大部分现代操□□作系统都提供□□□□了一些编程库□□□来促进 国际化 的发展,或者将软件调□□□整为支持多种▲语言的。国际化(通常简写为 i18n,节选自 i-nternationalizatio-n)库通常都会将□□□□应用程序的文□□本资源(按钮标签、用户界面[UI] 提示和菜单选□□□项)保存成多种语□□言的。在启动国际化□□□后的应用程序□□后显示哪种语□□言,这要取决于用✦户的区域设置 —— 通常,这是一个可配□□□□置的系统或个◤人帐号优选项。

  理想来说 —— 至少对于独立□□软件供应商来□□□说 —— 相同的可执行•程序以日语或□□□□希腊语运行时□□都能运行得一◥样好。然而,构建 “本地方言” 版本的应用程□□□□序的情况远远□□没有这么理想。包括被广泛认□□□□可的 ISO(International Standards Organization)/IEC(International Engineering Consortium)10646 和 Unicode,没有哪种字符□□编码可以解决□□□如何实现任意□□□□语言的输入和□□□呈现问题。ISO/IEC 10646 和 Unicode 只指定了如何◎存储、检索和排序字□□□符以及字符的◉特殊组合。例如,这些标准并没□□□有规定统一的□□□格式、嵌入式数据或□□□□标识来让使用◇泰国语书写的□□文档怎样才能◤按照泰国 语的规范规则□□□□正确地呈现出○它们的样子来。是的,Unicode 可以维护使用□□□泰国语书写的★文档的内容,也可以保证这●种文件在所有♦使用 Unicode 的平台上都可□□以很好地进行□□□移植,但是它并不能□□保证我们可以·正确查看文件,也不能保证文□□档所呈现出来□□□□的样子与作者□□□□的意图一致。

  我们来考虑一□□下这种情况:尽管 Linux GNU C 库(glibc)提供了一些函□□数来处理 ISO 10646 兼容的 31 位字符,但是它并不能□□□保证这些字符□□可以在显示设◉备上正确进行◤显示。有些 glibc 字符串函数,例如 strcat() 和 strlen(),都可以正确地□□□□处理多字节的□□□□问题,但是要正确显□□□□示阿拉伯语,需要双向(bidi)显示的功能,这种功能只有□□□在图形用户界□□□面(GUI)工具 包和专用字符♦串显示库中才□□□□能找到。

  例如,GNOME 需要 GTK+ 工具包和 Pango(一个文本显示◥库)来实现对 i18n 的完整支持(然而,Pango 在解决自己用▽途不够广泛方□□面有一些限制。请参看侧栏 pango 的问题)。其他 GUI 工具包提供了□□□□对 i18n 的支持,但却并不总是□□□能兼容这些标□□□□准。当然,Linux 上的图形应用□□□程序也需要 X Window System 的基本显示库 Xlib,它提供了两种□□□绘图(形状和线条)和字符显示原□□□语。不幸的是,Xlib 只能显示西欧◥语言。

  Pango 的问题

  Pango 可以放置(布局)并显示一些复□□杂的手稿,但是不能对多◉字节的文本进□□□行排序或搜索□□功能。Pango 假设底层库 —— 通常是使用 C 语言编写的,可以对使用 Unicode 标准指定的所□□□□有语言都进行□□□操作 —— 可以执行基本△的文本处理操□□□□作。

  一个库显示所□□□有语言

  要让应用程序✦在全球都可以□□使用 —— 而不会在西方▽国家和世界上※其他很多语言▽之间产生不公□□□平的现象 —— 我们必须要能□□够 输入、存储、提取并 显示 任何语言,而不管这究竟◣会多么复杂。正如上面介绍□□□的一样,有一些广为认丨可的标准为多□□□字节存储和可□□移植性提供了★一些便利;然而,现在还没有为□□输入和显示制□□□□定 标准。更加糟糕的是,即使是好的多◤语言文本编辑□□器也会被迫混□□□□合使用简单的□□□□国际化库和私□□有 GUI 工具包。添加一种语言□□□可能会需要另◤外一种(很可能是新的)定制库。

  Multilingualization Library 或 m17n 库会尽力为类 UNIX 平台上多种语□□□□言书写的文本□□□的输入、处理和显示提□□供一种单一的□□解决方案。另外,m17n 的目标是充分◇利用现有且大△家都可以很好□□□□地理解的典型 UNIX 应用程序框架,而不是利用软□□件开发人员的□□□其他模型。

  后,m17n 会努力使国际□□□□化的内容更加◎丰富,而不仅仅是简◈单地从英语移□□植到另外一种◥语言上。使用 m17n,同一个二进制□□文件可以在一□□□□个系统上显示□□□□法语,在另外一个系□□□□统上显示蒙古□□语,甚至在同一个□□屏幕上就可以□□□□显示多种语言□□□的文本。更好的是,m17n 可以(令人信服地)实现诸如文本□□数据库之类的□□□功能,这使它可以存□□□储并处理大量□□的国际化内容。

  m17n 库是在日本 Tsukuba 的 National Institute for Advanced Science and Technology 工作的 4 个日本程序员◤编写的。很多年以来,日本都一直走□□□在了国际化的□□□前端,部分原因是日□□语学者一直在□□□试图为人文学◣科探索一种百□□科全书式的方◉法 —— 尤其对世界上◆各种语言更为□□□□关注。

  m17n 库是由 3 个库和一个存□□□□储单一脚本以●及正确显示脚◇本所需要的元□□□数据的数据库□□□构成的:

  m17n C 库可以类似地❖实现 glibc (以及各种风格□□的 libc )的一些基本的▼文本处理功能。

  m17n X 库与 Xlib 是紧密对应的。它提供了基本□□□的绘制字符的❖功能,并且对呈现所□□做的假设很少。

  m17n 工具包提供了▽一些功能,可以对复杂的□□□脚本进行处理,使它们可以准□□□备好在屏幕上□□□进行显示。例如,泰国语在显示□□之前,必须进行排序、合成和重新排□□序。

  后,m17n 数据库存储了◉每种语言所特□□有的一些数据。例如,某种特有语言□□□□可能会需要自□□□□己的字体、一种特定的编★码以及一些特□□□□殊的机制来输□□□入自己的数据。m17n 库是与语言无◉关的;m17n 数据库中保存□□□了所有与语言◢有关的信息。

  图 1 给出了 m17n 的 4 个部分,以及这些库是□□□如何与现有的□□系统组件对应□□的。m17n 组件和传统 UNIX 库之间存在惊□□人的类似之处□□并不意外:m17n 的创建者希望◆能够让多语言□□□的应用程序的□□□□编写尽量简单。我们只要使用□□一个等效的多□□□语言库来替换□□相同语义的函□□□□数即可。

  (从侧面来看,m17n C 和 X 库就预示着 X 服务器可以提·供国际化功能。不过,m17n 对底层操作系□□统和呈现机制△的假设较少,因此我们可以▽将 m17n 移植到其他窗◣口系统上。实际上,将 m17n 集成到跨平台□□□的 GUI 工具包(例如类 UNIX 系统上使用的 Qt)正是当前的工□□作重点,m17n 团队正在将自※己的代码加入 GTK 的修正版本中。)

  字符一瞥

  添加新拼字法□□也非常简单:不需要改编 m17n 库来显示新脚□□□本。相反,只需要创建一□□□□个新的 m17n M-text,并将 M-text 添加到 m17n 数据库上即可。

  可以将 M-text 当作一个泛化△的 C 字符串,因为这就可以□□□将任意属性添□□□加到通常与 C 字符串有关的□□□□字符代码中。一个属性可以□□□指定语言要显□□□□示的字符,而另外一个属○性则可以指定□□□特定的字体。Bidi 信息也是使用 M-text 表示来进行编□□□码的,并且基本的字○形信息都可以□□出现。

  例如,图 2(已经得到 m17n 开发人员的许□□可进行复制)展示了这些属○性如何用来修□□□□改文本字符串□□□的外观。这个字符串非□□□□常简单,内容是 “This is sample text to show the property”。然而,每个字符串都□□有一个 face 属性 —— 或多个 face 属性 —— 它决定了要使◢用哪些字体来□□□显示字符。该图中所显示□□的 face 属性都故意进□□□行了简化,但是我们可以□□□看到这种特性◤所提供的灵活□□性,这对于世界上□□很多手写语言□□□□来说都是必要□□的。

  有很多脚本都□□□□需要复杂的过□□□□程来重新进行□□排序,或重新放置各△个要显示的复□□杂合成图形。诸如泰米尔语、缅甸语和泰国□□□语之类的脚本•在进行显示之☆前都需 要这种重新排□□序过程。作为更为具体□□□□的一个例子,图 3(也已经获得作□□□者许可进行复□□□□制)展示了单词 Hindi 是如何进行处□□理来使用 Devanagri 脚本正确显示□□□的。这需要两个阶□□□□段。先进个阶段是◥将字符序列从□□□字节顺序(字符在内存中◤如何存储)转换成正确的□□□手写顺序(字符如何在纸□□□面上显示)。

  第二个阶段负▽责扫描特有的□□□□字形和读音序○列(如果存在)并将这个序列◢替换成 “复合” 字形(英语有很多这□□□□种转换来增强□□□文本的可读性。根据所使用的□□□□字体的不同, f 和 i 序列通常都会✦使用一个 fi 字形代替,这要取决于我□□□们选择的字体)。

  这个重新排序▲过程的通用名◎字是 Complex Font Layout(CFL)。通常,CFL 信息都包含在□□□字体中,在某些情况中,已经写死到显□□□示库中了。在 m17n 中,CFL 信息可以在 FLT(Font Layout Table)中找到。有些拼字法需□□要少量的 FLT 数据;另外一些字符□□□□则需要很多信◈息来捕获复杂□□□□的规则。

  例如, Sino-Japanese orthography 就没有前后规□□□则可以影响单□□□个字形组合的□□□□复合。然而,泰国语的确有□□□□一些有趣的规□□□则可以影响 orthography 的变化,但是它对于泰□□□国口语不会产□□生任何影响。泰国语的拼字□□□法 对于周围的文□□□本来说非常敏□□□□感,但是对于口语□□□来说则并非如★此。印度脚本中特○定的组合规则□□也相当复杂,必须使用 FLT 来显示。

  后,诸如字体、双向显示、Unicode 和语言之类的◆数据都会将文□□□本的显示呈现□□□□在屏幕上。下一个棘手的◣问题 —— 也可能是现在▼正出现在您脑□□□□海中的问题 —— 是我们如何以□□非 ASCII 字体的形式来□□□输入文本。

  使用有 500 个键的键盘

  对于英语和很□□□□多欧洲语言来□□说,一个字符映射□□□□为一个键(或两个键)就足够了。大写键可以直□□□□接打印,键盘驱动程序□□可以对很多更□□□为特殊的情况丨进行编码,但是其模型是□□相同的:按下一个键就▲代表输入某个□□特定的字符。

  那么,如果一种拼字□□法中有数百个□□□字符,或者更特殊一□□□点,它们之间有很·多组合,情况如何呢?那么我们就不□□□能简单地使用□□一次击键来实□□现了,而是需要使用 击键序列 ,或者快速连续□□□输入多个键。有一种特别的□□软件叫 输入法,它可以将每个□□键盘序列转换□□成一个字符或□□□一系列字符。

  当然,有些击键序列□□可能就是一次□□□击键。另外,我们可以创建•一种输入法将□□□□标准的拉丁字□□□母键盘 转换 成其他语系的□□拼字法。例如,老式的日语键□□盘就将拉丁字□□□□母转换成平假□□□□名和片假名。然而,试图使用 26 个字母(A 到 Z 的拉丁字母)表示大约 46 个平假名有些□□□困难。

  键盘映射、击键序列以及□□□□音译输入法都♦可以使用 m17n 数据库来表示。这种方法很大□□□□的一个优点是□□□□可以将拼字法 的规则与应用□□□□程序代码清楚□□地区分开来。应用程序代码☆适合由程序员□□来开发;如何显示正确·的文本则是语□□言学家的工作。

  获取 m17n 库

  正如上面介绍□□□的一样,m17n 包括 3 个库和 m17n 数据库。现在,我们可以使用□□□一个 m17n libc,另外还可以使□□□用一个 Xlib 的 m17n 版本进行编码。开发团队正在▲努力编写第 3 层的库即 m17n X 工具包,它将成为 GTK+ 的一部分。m17n 开发人员也从□□□事语言绑定的□□□□工作,这样诸如 Perl 和 Ruby 之类的编程语□□□言就都可以使□□用 m17n 了(这个工具包和□□□□绑定何时可用,尚没有进度表)。m17n 库也已经被接□□□纳为 Linux Standard Base(LSB)的一个部分,它可能会成为 Linux 国际化标准实□□□□现的一个很好□□□□的部分。

  m17n 库的新版本是 1.3.3,这是在 2006 年 2 月 22 日发布的。我们可以按照♦下面的方式来□□□□获取 m17n 库:

  下载 m17n 源代码。这个下载页面□□□□中还提供了使△用英语和日语◈编写的程序员□□□□文档包。

  如果喜欢使用 CVS(Concurrent Versions System),也可以使用下◤面的 CVS 命令来下载代□□□□码:

  $ cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/m17n login

  $ cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/m17n co m17n-lib

  $ cvs -d :pserver:anonymous@cvs.m17n.org:/cvs/m17n co m17n-db

  从源代码开始□□□编译程序也非□□□常简单:m17n 库使用了典型□□□的配置脚本来•配置系统,并为编译和安□□装创建合适的 Makefile(详细内容请参□□□□看 m17n 软件包中的 README 文件)。

  如果碰巧使用□□的是 Debian 的发行版本,就可以使用非○常方便的 APT 安装工具来安丨装 m17n 库和它所依赖▼的库。例如,要寻找 Debian 系统上所有可□□□□用的 m17n 包,就需要使用 apt-cache,例如 apt-cache search m17n。

  根据 APT 所指向的 Debian 储存库的不同,可能会看到如□□□□清单 1 所示的输出内□□□容。

  清单 1. apt-cache search m17n 命令的输出结□□□□果

  libm17n-0 - a multilingual text processing library - runtime

  libm17n-dev - a multilingual text processing library - development

  m17n-db - a multilingual text processing library - database

  m17n-docs - a multilingual text processing library - documents

  m17n-env - set up multilingual X environment

  m17n-lib-bin - a multilingual text processing library - utilities

  mlterm-im-m17nlib - MultiLingual TERMinal, m17nlib input method plugin

  在找到包名之●后,就可以运行 apt-get install 来自动下载并□□□□安装 m17n 包了。根据 m17n 开发人员的说□□□□法,为 Fedora Core、Mandrake、SUSE Linux 和 Gentoo Linux 提供的包也都□□□□可以使用。

  m17n 库依赖于几个□□□□其他库,这几个库在您□□□的系统上可能※有,也可能没有。请阅读前提条□□□件中新的列表。

  m17n 简介

  从内部来说,m17n 库会被组织成□□几个应用程序□□□□接口(API):

  Core:这个 API 提供了处理 M-texts 的功能。Core API 并不需要 m17n 数据库。

  Shell:Shell API 增加了 m17n 的数据库查找□□□□和搜索功能。Shell 包括了这个 API 的所有功能和□□□特性。

  GUI:GUI API 提供了在图形□□□□显示设备上输□□□□入并显示文本☆的功能。GUI 隐式地包含了 Shell 和 Core API 的所有特性。

  Miscellaneous:这个 API 定义了几个函◈数来帮助对 m17n 库进行调试和□□□□跟踪。

  m17n 库的使用与其□□他 Linux 或 UNIX 的库的使用相□□□同。如果要使用这▽个库的所有特◈性,就需要在程序□□中包含 m17n.h 头文件,然后在链接选●项中加上 -lm17n 选项,这可以在 Makefile 中实现。 如果只想使用 m17n 的一部分功能,Core、Shell、GUI 以及 Miscellaneous API 每个都有单独★的包含文件。不幸的是,m17n 并没有很多样□□□例代码,很多明显引用◥它们的程序,例如可以识别 m17n 的应用程序,也只有两年的▽时间。然而,m17n 的软件开发包(SDK)确实包含了一□□□个简单的程序,它可以使用各◤种编码来显示□□□文件。我们可以查看✦一下所下载的 m17n 工具包中的 example 目录。在这个目录中,打开 mview.c 文件。这个文件的一●部分如清单 2 所示。

  清单 2. m17n 示例文件

  ...

  325 M17N_INIT ();

  326 if (merror_code != MERROR_NONE)

  327 FATAL_ERROR ("%sn", "Fail to initialize the m17n library.");

  328

  329 /* Decide how to decode the input stream. */

  330 if (coding_name)

  331 {

  332 coding = mconv_resolve_coding (msymbol (coding_name));

  333 if (coding == Mnil)

  334 FATAL_ERROR ("Invalid coding: %sn", coding_name);

  335 }

  336 else

  337 coding = Mcoding_utf_8;

  338

  339 mt = mconv_decode_stream (coding, fp);

  340 fclose (fp);

  341 if (! mt)

  342 FATAL_ERROR ("%sn", "Fail to de

  code the input file or stream!");

  343

  344 {

  345 MPlist *param = mplist ();

  346 MFace *face = mface ();

  347

  348 if (fontsize)

  349 mface_put_prop (face, Msize, (void *) fontsize);

  350 mplist_put (param, Mwidget, shell);

  351 mplist_put (param, Mface, face);

  352 frame = mframe (param);

  353 m17n_object_unref (param);

  354 m17n_object_unref (face);

  355 }

  356

  357 /* Create this widget hierarchy.

  358 Shell - form -+- quit

  359

  360 +- viewport - text */

  361

  362 form = XtCreateManagedWidget ("form", formWidgetClass, shell, NULL, 0);

  363 XtSetArg (arg[0], XtNleft, XawChainLeft);

  364 XtSetArg (arg[1], XtNright, XawChainLeft);

  365 XtSetArg (arg[2], XtNtop, XawChainTop);

  366 XtSetArg (arg[3], XtNbottom, XawChainTop);

  367 XtSetArg (arg[4], XtNaccelerators, XtParseAcceleratorTable (quit_action));

  368 quit = XtCreateManagedWidget ("quit", commandWidgetClass, form, arg, 5);

  369 XtAddCallback (quit, XtNcallback, QuitProc, NULL);

  370

  371 viewport_width = (int) mframe_get_prop (frame, Mfont_width) * 80;

  372 viewport_height

  373 = ((int) mframe_get_prop (frame, Mfont_ascent)

  374 + (int) mframe_get_prop (frame, Mfont_descent)) * 24;

  375 XtSetArg (arg[0], XtNallowVert, True);

  376 XtSetArg (arg[1], XtNforceBars, False);

  377 XtSetArg (arg[2], XtNfromVert, quit);

  378 XtSetArg (arg[3], XtNtop, XawChainTop);

  379 XtSetArg (arg[4], XtNbottom, XawChainBottom);

  380 XtSetArg (arg[5], XtNright, XawChainRight);

  381 XtSetArg (arg[6], XtNwidth, viewport_width);

  382 XtSetArg (arg[7], XtNheight, viewport_height);

  383 viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, form,

  384 arg, 8);

  385

  386 /* Before creating the text widget, we must calculate the height of

  387 the M-text to draw. */

  388 control.two_dimensional = 1;

  389 control.enable_bidi = 1;

  390 control.disable_caching = 1;

  391 control.max_line_width = viewport_width;

  392 mdraw_text_extents (frame, mt, 0, mtext_len (mt), &control,

  393 NULL, NULL, metric);

  ...

  下面对这些代□□码详细介绍一○下:

  第 325 行负责对 m17n 库进行初始化。

  第 330 行的 coding_name 变量源自于一□□□□个指定输入文□□件编码的命令□□行参数;如果没有提供□□这种命令行,就使用 UTF-8 编码。

  第 339 行读取到达的✦数据,并根据编码类□□型对其进行解□□码,现在都反应在 coding 中。

  第 345 到 354 行设置要画的□□□文本框架。第 345 行从手头的 M-text 中提取出一些◢属性,而 346 行则提取出给□□□定文本使用的◇适当字体。第 348 行设置要显示□□使用的字体大□□□小(fontsize 是另外一个命□□□令行参数),第 350 和 351 行设置该框架▼中要画的其他◆属性,包括要画到哪□□□个小部件上(前面的 shell = XtOpenApplication (&context, "M17NView", NULL, 0, argc, argv, NULL, sessionShellWidgetClass, NULL, 0) 和后的类型定□□□义。

  第 362 到 383 行是典型的 X 工具包调用,用来设置应用□□□程序的主窗口。第 371 到 372 行负责计算对□□□于本地拼字法□□的一个 80 x 24 的窗口来说,视口应该多大。

  后,在为 M-text 呈现设置一些□□□□参数之后,在 392 行就会开始显□□□示 m17n 文本。

  总而言之,上面对这段代◆码片段的简短□□□□分析就说明了□□□在标准的 X 应用程序中通※常要执行哪些□□□操作。在很多情况中,创建一个多语□□□言的应用程序□□□□只需要很少的♦额外代码就可□□□以实现,这需要采用 m17n 的函数,而不是传统的 X 调用。

  展望

  如果没有可以□□□□构建 m17n 代码的系统,也不要烦恼。您仍然可以通□□过在线 m17n 呈现演示来体□□□□验这个库的作□□用。

  据开发人员说,他们正在继续◥在 GTK+ 中集成 m17n —— 这是扩宽 m17n 的认可程度以◇及影响力的下□□□□一个必不可少□□□□的步骤。现在,m17n 项目缺少样例□□代码供参考和□□□□扩展。建立更好的文□□□档也是另外一□□□个需要做的工○作,这与为主流平▽台提供二进制□□文件一样重要。然而,m17n 确实承诺会对✦各个省的方言□□□□也能够实现 WYSIEYG 的编辑。这对任何语言□□□□来说都是个好□□□□消息。

  个人计算机已▼经不再是什么□□□新奇的东西了。实际上,在不到 20 年的时间内,计算机已经成□□□□为了家庭的日□□□□常用品 —— 只不过它不是□□□□什么衣服之类□□的东西,而是用来管理◈信息的工具。然而,有些国家计算□□机的获得和使□□□□用还并不普遍。为了平衡这种♦不平等,需要让这些国□□□□家能够获得负 担得起的各种□□□□计算机硬件和□□□□软件。另外,还要保证本土▽居民能够以本□□□□地方言来使用□□计算机。

  m17n 库构建在 Unicode 和其他标准之◢上,用来根据手写□□语言的规则画◥出任意复杂的□□□□拼字法。它将代码与字□□□符的格式区分□□□□开来,因此相同的代◉码可以反复使◎用,甚至是在相同□□的应用程序中□□□呈 现不同的拼字□□□□法都可以。随着这些工作□□□□的不断进展,m17n 正在逐渐让计□□算机语言变成□□一种全球的方□□□□言。

← 上一篇 下一篇 → 返回首页
如有意向,请联系我们的客户经理
我们会根据您的需求为你制定详细的解决方案
在线咨询 or 拨打业务热线:135-9299-6491
在线咨询
咨询在线客服
热线电话
解决方案
扫一扫

扫一扫
关注k8凯发一触即发

全国咨询热线
135-9299-6491

返回顶部