【问题标题】:Qt, MSVC, and /Zc:wchar_t- == I want to blow up the worldQt、MSVC 和 /Zc:wchar_t- == 我想炸毁世界
【发布时间】:2011-05-30 02:33:13
【问题描述】:

所以 Qt 在 windows 上是用 /Zc:wchar_t- 编译的。这意味着 wchar_t 不是某个内部类型的 typedef(我认为是 __wchar_t),而是unsigned short 的 typedef。真正很酷的一点是 MSVC 的默认值正好相反,这当然意味着您使用的库很可能是使用 wchar_t 编译的,它与 Qt 的 wchar_t 类型不同。

这当然不会成为问题,除非您尝试在代码中使用 std::wstring 之类的东西;特别是当一个或多个库具有接受它作为参数的函数时。实际发生的情况是您的代码可以愉快地编译,但随后无法链接,因为它正在使用 std::wstring<unsigned short...> 查找定义,但它们只包含期望 std::wstring<__wchar_t...>(或其他)的定义。

所以我做了一些网络搜索并遇到了这个链接:https://bugreports.qt.io/browse/QTBUG-6345

根据 Thiago Macieira 的声明,“抱歉,我们不会支持像这样构建 Qt”,我一直担心修复 Qt 以使其像其他所有东西一样工作可能会导致一些问题,并且一直在努力避免它。我们用 /Zc:wchar_t- 标志重新编译了我们所有的支持库,直到几天前我们开始尝试移植(我们正在从 Wx 切换到 Qt)一些序列化代码。

由于 win32 的工作原理,并且因为 Wx 只是包装了 win32,我们一直使用std::wstring 来表示字符串数据,以使我们的产品尽可能地为 i18n 做好准备。我们做了一些测试,当尝试打印特殊的东西时,Wx 不能处理多字节字符(即使不是像度数符号这样特殊的东西也是一个问题)。我不太确定 Qt 是否存在这个问题,因为 QString 不仅是底层 _TCHAR 类型的包装器,而且是某种 Unicode 怪物。

无论如何,boost 中的序列化库已经编译了部分。我们曾尝试使用 /Zc:wchar_t- 重新编译 boost,但到目前为止,我们试图告诉 bjam 这样做的尝试都没有受到重视。我们陷入了僵局。

从我现在的位置,我有三个选择:

  1. 重新编译 Qt 并希望它能与 /Zc:wchar_t 一起使用。网络上有一些证据表明其他人已经这样做了,但我无法预测会发生什么。所有在论坛等上询问 Qt 人的尝试都没有得到答复。见鬼,即使在那个错误报告中,也有人问为什么,它就在那里呆了一年。

  2. 继续与 bjam 战斗,直到它倾听为止。现在我有一个在我手下做这件事的人,我有更多的经验来为得到我想要的东西而奋斗,但我不得不承认我已经厌倦了。我还担心我会继续遇到这个问题,只是因为 Qt 想成为一个 c**t。

  3. 停止使用 wchar_t 处理任何事情。不幸的是,我的 i18n 体验几乎为 0,但在我看来,我只需要在 QString(它有一个 BUNCH)中找到往返函数的权利,即可将 Unicode 编码为 8 字节,反之亦然。 UTF8 函数看起来很有希望,但我真的想确保,如果来自某个地方的具有更多符号语言的人开始用他们自己的语言编写,并且 QString 中的文档让我有点害怕认为可能发生这种情况,那么不会丢失任何数据。当然,我总是会遇到一些坚持我使用 wchar_t 的库,然后我又回到 1 或 2,但我很怀疑这会发生。

那么,我的问题是什么...

以下哪个选项是我最好的选择? Qt 是否最终会让我挖出自己的眼睛,因为我决定用 /Zc:wchar_t 编译它?

用 /Zc:wchar_t- 获得提升的魔法咒语是什么?这会造成永久性的精神伤害吗?

我可以只使用标准的 8 位(好吧,无论如何都是“通用”)字符类并符合 i18n 标准/准备好了吗?

其他 Qt 开发人员如何处理这个烂摊子?

【问题讨论】:

  • +1 炸毁世界。 (不过,我和 Vogons 打败了你。我已经完成了 42 次,而我的 Vogon 伙伴只得了 37 分。)
  • 这是其中一个在您遇到问题之前听起来并不重要的问题。我现在坚持使用 Qt4,但在 5.0.0 中似乎是 has been fixed。目前,您描述的第三个选项似乎是唯一可行的选项。

标签: c++ qt boost internationalization


【解决方案1】:

我同意 Öö Tiib 的评论

该选项可能适用于 与一些旧遗产的兼容性 预 wchar_t 代码。

考虑到 Qt 被移植到许多不同的平台(包括嵌入式系统),其中一些没有像样的 C++ 编译器,我猜这个开关只是为了让在这些平台上编译 Qt 成为可能。我的意思是它可能不是 Qt 正常工作所依赖的东西。如果是这样的话,在我看来,这意味着 Qt 的设计被严重破坏了。所以选项1应该有效。

话虽如此,我肯定会推荐选择选项 3,因为

  • wchar_t 几乎没有给你任何东西 关于 i18n
  • 你注意到 Qt 有非常强大的字符串类 这使得 i18n 成为一项简单的任务(参见 Internationalization with Qt)

您可以查看results 或在qt-interest@qt.nokia.com 列表中搜索wchar_t,在那里提出您的问题并在freenode.net #qt irc 频道与Thiago Macieira 交谈,Thiago 非常活跃。

【讨论】:

    【解决方案2】:

    偶然发现了同样的问题...... 显然 bjam 期望 cxxflags=-Zcwchar_t-

    通过

    构建静态序列化库后

    bjam --with-serialization toolset=msvc-8.0 variant=debug threading=multi link=static cxxflags=-Zc:wchar_t-

    一切都按预期链接。

    希望这对任何人都有帮助。

    【讨论】:

    【解决方案3】:

    将其放在这里作为答案,因为评论太长了。

    这是为什么人们可能会收到 LNK2019 又名“未找到符号”链接器错误 (source) 的答案之一:

    • 您将使用本机 wchar_t 的代码与不使用本机 wchar_t 的代码混合在一起。在 Visual C++ 2005 中完成的 C++ 语言一致性工作
      wchar_t 默认为原生类型。您必须使用 /Zc:wchar_t-
      生成与由
      编译的模块兼容的代码的编译器选项 使用早期版本的 Visual C++。如果不是所有模块都已完成
      使用相同的 /Zc:wchar_t 设置编译,类型引用可能
      不解析为兼容的类型。验证 wchar_t 是否输入了所有
      模块是兼容的,或者通过更新使用的类型,
      或者在编译时使用一致的 /Zc:wchar_t 设置。

    因此可能是 /Zc:wchar_t- 存在于所有与 cl.exe 相关的 mkspec 文件中的主要原因,也是您可能不需要它的主要原因。

    我喜欢使用原生 wchar_t,因为它有时可以很容易地在 windows api 期望的字符串和 QString 之间进行转换。

    【讨论】:

      【解决方案4】:

      wchar_t 应该是 bool 或 long 类型。不需要任何标题来定义它。

      您确实使用了“wchar_t 是未定义类型”选项。然后你 typedef wchar_t as unsigned short 然后你想知道什么都不管用了吗?

      该选项可能是为了与一些旧的 pre-wchar_t 代码兼容。只是简单地......永远不要使用它。否则,没有任何 C++ 链接到它,因为采用 wchar_t 参数的函数与采用无符号短参数的函数的名称修饰不同。

      如果某些库是用一些奇怪的选项编译的,那么用正确的选项构建它。需要时修复其代码。如果你做不到,那么你不应该使用那个库。 C++ 项目中的每一行代码都由您维护。

      【讨论】:

      • 这是mathematician's answer 的一个很好的例子。您基本上是在要求 OP 在一个庞大的库中修复未知数量的难以确定的错误,并无限期地维护上述修复,这违背了库作者的意愿。
      • 没有没有错误的库。在 Windows QT 上运行顺畅。只需尝试在装有奇怪的手持 Symbian 操作系统的诺基亚手机上编写一个 QT 应用程序,就可以了解不断维护他人垃圾的真正含义。
      • @Zac - 是的,当我询问如何以尽可能简单的方式使用它时,我认为“不要使用它”的答案非常可爱。直到现在才注意到编辑......可爱;可以肯定地说,Oo 不以编码为生。
      • 好吧。如果您使用其他人的代码并且不为维护支付任何费用,那么维护就是您的了。无论是boost还是QT。如果你不喜欢这个答案,没必要侮辱我。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多