[关闭]
@markheng 2020-07-12T11:46:13.000000Z 字数 2923 阅读 1217

基于QT的跨平台应用在国产化环境下的乱码问题研究

论文


概要

背景

国产化背景

当前开发模式

当前ZK软件开发普遍仍然采用VS2010+Qt4的开发模式,采用该种组合一方面是考虑到软件兼容性和软件设计师及开发人员的习惯,该模式经过多年实践验证,能够兼顾代码质量和开发效率;另一方面是行业软件设计师大多有着实时操作系统或嵌入式跨平台开发的经验,有经验积累和跨平台开发习惯。当国产化要求出现时,这套开发体系在Qt本身就可以跨平台的能力加持下,也能够胜任国产化要求下的软件开发任务。

存在的乱码问题

VS2010+Qt4这一体系在通常的开发流程和逻辑处理方面并不存在任何问题,一套代码在不同平台下进行编译之后即可直接运行,但是由于早年Windows和Linux操作系统对于文件的编码处理或者说实现理念并不一致,导致两个操作系统在当今流行的编码字符集的处理上存在些许的差异,这些差异在跨平台情况下造成中文乱码问题。跨平台的乱码问题为设计师和整个软件产品带来诸多不利影响,定位乱码问题有时需要消耗大量精力,降低整个软件系统开发效率。某些情况下乱码问题还会产生连锁反应导致软件产品失控,产生不可预估的行为,影响产品质量。此外,人机交互界面的乱码问题造成不好的用户体验,进而10影响产品口碑。

国产化平台与Windows平台的编码

国产化平台介绍与编码介绍

当前国产化操作系统主要包括银河麒麟和中标麒麟,两款操作系统都属于麒麟软件公司,既面向通用领域打造安全创新操作系统和相应解决方案,又面向国防专用领域打造高安全高可靠操作系统和解决方案,除了服务器操作系统、桌面操作系统,还有嵌入式操作系统、麒麟云等产品,能够同时支持龙芯、飞腾、兆芯、申威、海光、鲲鹏等国产处理器。

无论银河麒麟还是中标麒麟,本质都是基于Linux内核进行自主开发、符合POSIX标准[xx]的类UNIX操作系统,在软件编码上采用与国际主流Linux发行版相同的策略,即对Ascii编码处理不了的编码,默认采用UTF-8进行处理,可以通过人工设定兼容Unicode、GBK等字符集,应用程序在处理字符时需要考虑编码问题,如果读写的字符集和文件存储的字符集采用不同的字符集,就会导致乱码问题。

windows开发平台编码介绍

Windows操作系统默认使用Unicode对字符进行编码,以兼容世界上多种多样的语言文字。在中文环境下,Windows默认使用GBK编码[https://zh.wikipedia.org/wiki/%E6%B1%89%E5%AD%97%E5%86%85%E7%A0%81%E6%89%A9%E5%B1%95%E8%A7%84%E8%8C%83]进行处理,由于中文GBK编码与UTF8并不兼容,因此,在Windows下编写的源代码,在国产化平台上使用UTF8进行处理,便会出现乱码。

Windows操作系统对UTF8也是提供支持的,但是Windows中的应用程序,如VS2010、记事本等,存储的UTF8格式文件,默认会在文件头添加字节顺序标记(Byte-order Mark,BOM),以便于程序能够正确进行解码。而在类Unix系统中,存储的UTF8文本文件并不会在文件前面含有BOM,因此将国产化平台下生成编写保存的源代码拷贝到Windows平台下进行编译,会因为编译器提示存在不可解析的字符而无法编译的问题。

Qt与标准C++中的字符串及编码

标准C++中的字符串与编码

标准C++中,提供两种类型对字符进行表示,一种是窄字符类型char,一种是宽字符类型wchar_t,wchar_t支持unicode编码,但是需要开发人员使用时调用对应的应用程序接口(API),给程序编写带来不必要的麻烦。而且C++标准库中提供的字符串类(std::string)内部采用char类型对字节数据进行存储,并且不针对传入的字面量进行任何转换处理。

Qt中字符串与编码

在Qt应用程序中,界面的中文字符显示和人工输入等内容大部分通过字符串实现,Qt中对字符串的处理主要通过QString类以及其它与之相关的类完成。为了兼容多种语言,QString内存储字符默认采用双字节Unicode4.0编码进行存储,因此在将字符变量或者C++标准字符串变量传入QString时需要采用Qt提供的转换手段进行编码转化,否则会出现乱码问题。

Qt应用程序跨平台乱码研究

为了研究清楚跨平台情况下Qt应用程序乱码问题的原理,并且找出两个平台下均可进行正常代码编辑、正常编译的方法,我们设计了实验进行验证。

验证条件:
表xx 操作系统 编译器 代码编辑器

图1
源代码阶段 编译阶段 部署阶段
[图] VS2010/QtCreator编辑代码 =》cl编译器/g++编译器进行编译 =》本地调试 =》应用部署

ZK系统跨平台应用程序开发流程如图所示,首先由开发人员在VS2010或QtCreator等编辑器中,完成代码编写,再经过编译器(Windows平台为cl[参考xxx],国产化平台为g++[参考xxx])编译生成可执行程序,最终在各自平台上运行。

源代码编写,通常在Windows平台进行,由于VS2010不支持设置新建文件的默认编码设置,因此如果不进行特别设置的情况下,用VS新建的源代码文件均为GBK编码,如果需要在国产化平台上进行编译,需要将Qt的TextCodec设置为GDK编码,但是带来的问题是在国产化平台修改源代码文件时,都需要手动设置读取文件的编码为GBK,否则注释等内容都会乱码。

如果使用QtCreator进行源代码编写,自动生成文件编码默认为不带BOM的UTF8编码格式,这种格式又会导致cl编译器无法进行编译,必须转换为带BOM的UTF8编码或者GBK编码才能在Windows上正常编译调试。

如果在Linux平台上直接使用QtCreator进行源码编写,会面临与Windows平台下直接用QtCreator编写源码同样的问题,源码无法在Windows平台下正常编译,需要进行转码才可以。

经过以上实验,可以发现,Windows平台下由于编译工具要求源代码必须是GBK编码或者带BOM的UTF8编码才能正常进行编译,而GBK编码的源代码在国产化平台下又无法正常打开即进行编辑,因此需要将所有需要跨平台编译的源码都转换为带BOM的UTF8编码格式,这种编码格式的代码无论在Windows平台还是国产化平台都可以正常进行编辑、也可以正常进行编译、进行调试。

实验结果如下表

编码转换工具的设计与实现

编码转换工具的目的

经过实验,我们知道将源代码编码保存为带BOM的UTF8,可以“完美地”在Windows平台和国产化平台进行编辑、编译和调试,但是在实际开发过程中,总会有新的源码文件不断建立,无论是VS2010还是QtCreator新建的文件编码默认都不是带BOM的UTF8格式,新建后的项目中,就会包含两种或以上的文件编码类型,通过人工方法一个个将源码文件保存为带BOM的UTF8格式既耽误时间,也容易遗漏。为了解决这个问题,本文设计了一个编码识别转换工具。

设计内容

实现内容

结论

本文通过

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注