QT_NO_CAST_FROM_ASCII这个宏的,禁用一切来自双引号字符串字面量传入QString(有2种解决方法)

这两天制作了两个Qt Creator增强套装的两个插件,其实也是非常简单的,但是其实花了我超过四天的时间,为什么呢?因为我之前很长一段时间都是在Linux下开发的,一切安好,没有任何问题,但是到了Windows下,各种问题就暴露出来了。首先呢,就是——

1、Qt Creator源码中,默认是打开QT_NO_CAST_FROM_ASCII这个宏的,看文档,这个宏就是禁用一切来自双引号或者单引号的字符串字面量传入QString的函数。但是我们裸写字符串不是非常平常的一件事情么?这里是Qt Creator断了我们一条道路,解决的方法还是有的,我这里提供两个方法,欢迎提出新的方法: 
1) 在

include($$QTCREATOR_SOURCES/src/qtcreatorplugin.pri)

这一句后面添加

DEFINES -= QT_NO_CAST_FROM_ASCII

如果还有必要的话,那么还需要添加

DEFINES -= QT_NO_CAST_TO_ASCII

这些都是解除设定宏的好方法

2) 使用QStringLiteral宏来包裹字面量 
我还设计了两个宏,分别对应识别单个字符和字符串。他们分别是:

#define CHAR( c ) QChar( ushort( c ) )
#define TEXT QStringLiteral

这些都是非常方便的宏,可以很方便地替换掉裸写的字面量。

2、由于Windows下编译器有MinGW以及MSVC,我们要注意我们编写的插件是C++插件,是编译器相关的,比如说,MinGW编写的插件无法在MSVC编译器编译的Qt Creator上使用。遗憾的是,Qt Creator官方编译的都是MSVC的,而且有一个现象,不同的MSVC版本编写的Qt Creator依赖的Qt库,有一些函数的地址还不能通用。比如说和上面一个例子非常相似的例子,那就是我使用MSVC2015编译的Qt Creator插件,其中用到了QString::utf8()函数,但就是这个函数,无法在官方MSVC2013编译的Qt Creator中成功载入,提示“无法找到模块”。为什么呢?看看QString::utf8()函数源码吧:

#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP)
    QByteArray toLatin1() const & Q_REQUIRED_RESULT
    { return toLatin1_helper(*this); }
    QByteArray toLatin1() && Q_REQUIRED_RESULT
    { return toLatin1_helper_inplace(*this); }
    QByteArray toUtf8() const & Q_REQUIRED_RESULT
    { return toUtf8_helper(*this); }
    QByteArray toUtf8() && Q_REQUIRED_RESULT
    { return toUtf8_helper(*this); }
    QByteArray toLocal8Bit() const & Q_REQUIRED_RESULT
    { return toLocal8Bit_helper(constData(), size()); }
    QByteArray toLocal8Bit() && Q_REQUIRED_RESULT
    { return toLocal8Bit_helper(constData(), size()); }
#else
    QByteArray toLatin1() const Q_REQUIRED_RESULT;
    QByteArray toUtf8() const Q_REQUIRED_RESULT;
    QByteArray toLocal8Bit() const Q_REQUIRED_RESULT;
#endif

看出来什么吗?不同的预编译宏会导致不同版本的toUtf8()函数被编译,难怪Qt Creator发现QString::utf8()函数和自己Qt库中的这个函数地址不一致会报“无法找到模块”错误呢。

那,有没有解决的方法呢?由于Json格式化,一定要这样的函数,因此我打算看看它的源码,是否能够找到替代的实现方法。没错,就是

toUtf8_helper(*this);

中,我找到了

QUtf8::convertFromUnicode()

方法 
终于找到了这个方法,又偶然发现QTextCodec::fromUnicode()函数中隐含调用了上述函数,于是我这么操作:

    QTextCodec* utf8Codec = QTextCodec::codecForName( "UTF-8" );

    QString plainText = ui->jsonEdit->toPlainText( );
    QByteArray converted = QJsonDocument::fromJson( utf8Codec->fromUnicode( plainText ) ).
            toJson( QJsonDocument::Indented );
    plainText = utf8Codec->toUnicode( converted );

 

顺利实现效果!

开发Qt Creator的过程中,每一步都是一个坑。但万变不离其宗,只要你有耐心,找到规律,找到核心问题,相信你一定和我一样,最终会找到问题的答案的。

http://blog.csdn.net/gamesdev/article/details/52167294

posted @   findumars  Views(2637)  Comments(0Edit  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
历史上的今天:
2016-01-18 QT5.6所开放的7个新模块(图表,虚拟键盘,性能分析,静态分析,测试正好,2D渲染)
2016-01-18 ddd
2016-01-18 Qt 5.x 全局热键 for windows
2016-01-18 Qt 操作 pdf 文件
2016-01-18 Qt 获取字符串的UTF8编码值
2016-01-18 Qt写一个截屏工具(窗口透明)
点击右上角即可分享
微信分享提示