Windows上的QT:从GDB运行时无效的函数参数

时间:2015-07-03 09:34:43

标签: c++ qt

在配置为在Windows 7 x64下使用MinGW(来自32位QT发行版)的QT 5.4.2项目中,我发现程序正常工作正常但在GDB中崩溃的问题。我已经将崩溃追溯到从QML传递给我的回调函数的无效参数。它是在对象上定义的函数,用作上下文属性。该函数接收QString作为其参数。在没有gdb的情况下执行时,其值与预期值相同。使用gdb,它包含垃圾(不是随机垃圾,但每次都是相同的特殊垃圾)。示例代码:

class CallbackSink : public QObject {
    Q_OBJECT

public:
    CallbackSink() {}

    Q_INVOKABLE virtual QString callTestString2(const QString &str) { return QString(""); }

    virtual ~CallbackSink() {}
};


class Sink : public CallbackSink {
    Q_OBJECT

public:
    Sink() {}

    Q_INVOKABLE virtual QString callTestString2(const QString &str) {
        const char *_str = str.toUtf8().constData();
        printf("_str=%s\n", _str);

        const char *_ret = "fdsa";
        QString ret = QString::fromUtf8(_ret);
        return ret;
    }

    virtual ~Sink() {}
};

QT初始化代码:

gui.h:

struct Gui {
public:
    std::unique_ptr<QApplication> app;
    std::unique_ptr<QQmlApplicationEngine> engine;

    std::unique_ptr<CallbackSink> sink;

    QQuickWindow *window;

    Gui(std::unique_ptr<CallbackSink> s) : sink(std::move(s)) {}

    int run();

    virtual ~Gui() {}
};

gui.cpp:

int Gui::run() {
    char x[] = "BLAH BLAH";
    char *argv = x;
    int argc = 1;

    app = std::unique_ptr<QApplication>(new QApplication(argc,&argv));
    engine = std::unique_ptr<QQmlApplicationEngine>(new QQmlApplicationEngine());

    QQmlContext *objectContext = engine->rootContext();
    objectContext->setContextProperty("callbacks", &*sink);

    engine->load(QUrl("qrc:///myqml.qml"));
    QObject *topLevel = engine->rootObjects().value(0);
    window = qobject_cast<QQuickWindow *>(topLevel);
    window->show();

    int r = app->exec();

    return r;
}

相关的QML片段:

Text {
    id: mytext
    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
    textFormat: Text.RichText
    text: '<p>call 2: `' + callbacks.callTestString2('foo') + '`'
}

我想值得注意的是,我将所有GUI代码编译为DLL,并且可执行文件从单独的项目链接到它。

从gdb运行时,我看到这个打印出来(与论据值无关):

_str=ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■☺!=4/Ц♠↑☺

UPDATE :也尝试过Qt 5.5,同样的问题。

更新2 :我已经在QtCreator中从模板创建了一个新的QtQuick应用程序项目,并对其进行了少量更改以重现该问题。它也发生在这个项目中。

1 个答案:

答案 0 :(得分:2)

const char *_str = str.toUtf8().constData();
printf("_str=%s\n", _str);

这里有未定义的行为。 toUtf8()返回一个临时对象,该对象将在完整表达式结束时被销毁。 constData()返回一个指针,该指针在该临时对象被销毁后不能保证有效。试试这个:

printf("_str=%s\n", qPrintable(_str));