跨平台项目中QString 与 非Qt 跨平台动态库在字符集上的一个实用的互操作约定.

  1. Windows 系统字符集是 CP936, 即 GBK

  2. Linux 系统字符集是 UTF-8

  3. Windos 下, MSVC 的 binary 默认字符集是 GBK

  4. Linux 下, GCC 的 binary 默认字符集是 UTF-8

  5. UTF16_ANSI 就是将 UTF 16 转换成本地字符集. 这里本地字符集是 UTF-8(Linux), GBK( Windows ).

  6. ANSI_UTF16 是将本地字符集转换为 UTF16. 本地字符集的定义同上. 这里 UTF16_ANSI 和 ANSI _UTF 16 是我们自己编写的一个跨平台的函数. 在 Linux 下, ANSI效果等同于 UTF -8.

  7. 以上是我们编写跨平台且处理中文时关于字符集编码的约定.

  8. 基于以上的约定的动态库的 API 中, char * 和 std::string 的字符集都是本地字符集.

但是: 我们有少量项目使用 Qt. 当编译 Qt 项目的时候, 情况会有所不同.

  1. 在 Qt 环境下, 尽量用 QString. QString 的内部存储是 UTF -16.

  2. 但是 QString 不可避免的要和 多字节编码(UTF-8, GBK均属于多字节编码) 打交道,因此需要注意 QString 的字符集相关的用法

  3. QString::toStdString 返回的 std::string 其编码一定是 UTF-8 的,无论是 Windows 和 Linux 下. 这是 Qt 5, Qt 6 的强制约定.

  4. QString::fromStdString 总是认为输入的 std::string 是 UTF-8 编码,而不管它内容实际上是什么编码. 因此,如果在 Windows 下, std::string("中文") 用QString::fromStdString 转换后会是乱码, 而在 Linux 下正常. 因为 Windows 下, std::string("中文") 是以 GBK 保存的, 强行当作 UTF-8 解析必然乱码.

  5. 为了避免 第13 的问题, 可以将 MSVC 的编译选项中加上 /utf-8, 这样, MSVC 就会认为 C++ 的源码以及编译出来的 binary 中的字符串都是 UTF-8 的. 于是 std::string("中文") 即使在 windows 下也是以 UTF8 编码存在, 这样就和 linux 一样了. 这会大大简化在cpp 源码中 QString 与 std::string 的互转换的复杂性. 但要注意的是, cpp 源码一定得用 UTF-8 NO BOM 保存. 按照这个原则, QString 与 std::string 的互转在 linux 和 windows 下的行为一致.

  6. 第 14 条解决了 Qt 项目中 cpp 内部 QString 和 std::String 的互转问题. 但是要注意的是, 如果 Qt 项目需要与 DLL API 交互, 而这些 DLL 依然遵从第1~9 的约定(通常总是这样), 则 API 中的 char * 依然是本地编码. 这样, 按照第 14条, 在 Windows 下, QString::toStdString().c_str() 得到的 char * 传递给 DLL API 时会导致中文乱码. 因为 这个字符串是 UTF -8 的, 而 DLL API 期待的却是 GBK. 因此在这种情况下, 需要用 QString::toLocal8Bit().constData() 而非 QString::toStdString(). 同理, 当接收到 DLL API 输出的 char *, 需要用 QString::fromLocal8Bit( DLLAPI() ) 来将本能地编码的字符串转换为 QString.

  7. 类似的情况也出现在对 std:: 的各种函数的调用,例如 std::fstream 中的文件名, 它们是以动态库的方式提供,故文件名依然是本地编码. 这时也需要用 用 QString::toLocal8Bit().constData() 而非 QString::toStdString()

  8. 第14~16 是我们编写 Qt 跨平台代码时,关于字符集的约定.

相关推荐
上海广测检测科技有限公司1 小时前
消费类智能联网设备安全分级国标征求意见要点解析:三级五维框架与跨境对标逻辑
网络·经验分享
别动我齐刘海1 小时前
Linux 系统调试学习1
linux·运维·服务器·c++·学习·机器学习·机器人
富唯智能机器人3 小时前
晶振弹匣上下料,复合机器人如何实现柔性自动化|富唯智能
经验分享
小HANN5 小时前
华为云企业网站上云实战|从零搭建高可用WordPress全站架构(ECS+RDS+ELB+弹性伸缩+云监控闭环)
linux·运维·服务器·经验分享
GoppViper5 小时前
用户反馈驱动的智能搜索关键词动态优化系统
经验分享
jimy15 小时前
C++ 虚函数表:基类和派生类共用一张 vtable 吗?
开发语言·c++
爱吃提升6 小时前
Dev-C++ 5.11 C++断点调试完整教程
开发语言·c++
芯片智造6 小时前
硫酸盐体系与氨基磺酸盐体系NiFe镀液该如何选择?
经验分享
xlq223226 小时前
全面复习7
c++
geats人山人海7 小时前
现代c++2.4 虚继承
java·开发语言·c++