当前位置: 首页 > news >正文

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

1. Windows 系统字符集是 CP936, 即 GBK
2. Linux 系统字符集是 UTF-8
3. Windos 下, MSVC 的 binary 默认字符集是 GBK
4. Linux 下, GCC 的 binary 默认字符集是 UTF-8
6. UTF16_ANSI 就是将 UTF 16 转换成本地字符集. 这里本地字符集是 UTF-8(Linux), GBK( Windows ).
7. ANSI_UTF16 是将本地字符集转换为 UTF16. 本地字符集的定义同上. 这里 UTF16_ANSI 和 ANSI _UTF 16 是我们自己编写的一个跨平台的函数. 在 Linux 下, ANSI效果等同于 UTF -8.
8. 以上是我们编写跨平台且处理中文时关于字符集编码的约定.
9. 基于以上的约定的动态库的 API 中, char * 和 std::string 的字符集都是本地字符集.

但是: 我们有少量项目使用 Qt. 当编译 Qt 项目的时候, 情况会有所不同.
10. 在 Qt 环境下, 尽量用 QString. QString 的内部存储是 UTF -16.
11. 但是 QString 不可避免的要和 多字节编码(UTF-8, GBK均属于多字节编码) 打交道,因此需要注意 QString 的字符集相关的用法
12. QString::toStdString 返回的 std::string 其编码一定是 UTF-8 的,无论是 Windows 和 Linux 下. 这是 Qt 5, Qt 6 的强制约定.
13. QString::fromStdString 总是认为输入的 std::string 是 UTF-8 编码,而不管它内容实际上是什么编码. 因此,如果在 Windows 下, std::string("中文") 用QString::fromStdString 转换后会是乱码, 而在 Linux 下正常. 因为 Windows 下, std::string("中文") 是以 GBK 保存的, 强行当作 UTF-8 解析必然乱码.
14. 为了避免 第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 下的行为一致.
15. 第 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.
16. 类似的情况也出现在对 std:: 的各种函数的调用,例如 std::fstream 中的文件名, 它们是以动态库的方式提供,故文件名依然是本地编码. 这时也需要用 用 QString::toLocal8Bit().constData() 而非 QString::toStdString()
17. 第14~16 是我们编写 Qt 跨平台代码时,关于字符集的约定.

http://www.cnnetsun.cn/news/2192046.html

相关文章:

  • 喜马拉雅VIP音频下载终极指南:3步实现付费内容本地化
  • 对比直连与通过 Taotoken 调用在容灾体验上的不同
  • 终极免费d2s-editor:暗黑破坏神2存档修改完全指南
  • 【LLM推理优化与部署工程⑧】模型部署了,但没人知道它在干什么——出事了你都不知道
  • 终极魔兽争霸3优化指南:告别卡顿,畅享144Hz流畅体验
  • 中兴光猫解锁终极指南:5分钟获取完整root权限的完整教程
  • 八大网盘直链解析技术深度解析:架构设计与性能优化指南
  • PySpice终极指南:如何用Python轻松完成专业级电路仿真
  • 第24集:跨云多活架构!AIOps 平台的容灾与故障切换实战
  • QRCode 核心知识汇总
  • 告别盲配!用S32DS可视化工具高效搞定S32K3 MCAL时钟配置(以S32K312为例)
  • 八大网盘直链下载神器:告别限速烦恼的终极指南
  • VLingNav:视觉-语言-动作模型在智能导航中的应用与优化
  • 开源AI智能体编排平台Mission Control:从部署到生产级运维指南
  • RimSort:从模组下载失败到流畅管理的完整解决方案
  • 终极指南:三步轻松清理Windows驱动垃圾,释放数十GB空间
  • FanControl终极指南:免费开源Windows风扇控制软件,5分钟打造静音高效电脑
  • 从洗衣机到汽车:聊聊LIN总线这个‘经济适用型’协议在家电和车联网里的妙用
  • AKShare与Pandas完整整合指南:三步构建高效金融数据分析流程
  • 没人敢说的实话!《灵魂摆渡・浮生梦》怕了孤身闯局的海棠山铁哥和《第一大道》
  • 长期项目使用Taotoken在账单追溯与用量分析上的便利
  • 蓝桥杯单片机省赛拿分秘籍:第十一届这道‘电压阈值计数’题,我是这么啃下来的
  • 别再死记公式了!折叠共源共栅放大器设计中的5个关键权衡与选型思路
  • 分享一个微软开源的Python库用来扫盲转换 markdown格式 知识库
  • google搜索 cookie算法分析
  • CentOS 7/8远程桌面避坑指南:xrdp安装后黑屏、闪退?一次解决所有常见故障
  • 网盘下载太慢?这款开源工具让你免费解锁八大网盘直链下载
  • 抖音内容批量下载终极方案:告别手动录屏的智能工具指南
  • Go语言技能树实战:从并发模式到REST API的工程化演练
  • 强化学习在数学自动证明中的应用与优化