You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QtWebEngine内部对象typeid返回无效引用,该bug归属Qt/Chromium还是macOS?

QtWebEngine内部对象调用typeid返回无效引用的问题分析

当对QtWebEngine的内部对象(如QtWebEngineCore::RenderWidgetHostViewQtDelegateItem)使用typeid运算符时,会返回无效引用,甚至出现输出中typeid: nullptr的异常情况,调用typeInfo.name()会直接导致程序崩溃,这明显不符合C++标准中typeid的定义。

复现代码

#include <QTimer>
#include <QGuiApplication>
#include <QtWebEngineQuick/QtWebEngineQuick>
#include <QtWebEngineCore/QtWebEngineCore>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
    QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
    QGuiApplication app(argc, argv);
    class EventFilter : public QObject{
    public:
        using QObject::QObject;
        QSet<const QMetaObject*> visited;
        bool eventFilter(QObject* obj, QEvent*) override {
            const QMetaObject* mo = obj->metaObject();
            if(!visited.contains(mo)){
                visited.insert(mo);
                const std::type_info& typeInfo = typeid(*obj);
                // the following action may crash:
               // typeInfo.name();
               // prove it by checking the reference for validity:
                const std::type_info* typeInfoPtr = &typeInfo;
                if(mo && typeInfoPtr)
                    qWarning("metaobject: %s, typeid: %p (%s)", mo->className(), typeInfoPtr, typeInfoPtr->name());
                else if(mo)
                    qWarning("metaobject: %s, typeid: nullptr", mo->className());
                else
                    qWarning("metaobject: nullptr, typeid: nullptr");
            }
            return false;
        }
    } eventFilter;
    app.installEventFilter(&eventFilter);
    QQmlApplicationEngine engine;
    QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadData(R"(
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtWebEngineApplicationWindow {
    visible: true
    width: 500
    height: 400
    WebEngineView {
        id: webView
        anchors.fill: parent
        url: http://www.qt.io
    }
}
)");
    QTimer::singleShot(2000, &app, QCoreApplication::quit);
    return app.exec();
}

运行输出

metaobject: QtWebEngineCore::RenderWidgetHostViewQtDelegateItem, typeid: nullptr

问题根源分析

  1. 排除macOS系统层面问题:macOS的clang/libc实现的typeid完全符合C标准,常规场景下不会返回无效引用或nullptr,因此系统层面的可能性极低。
  2. Chromium层面的潜在原因:QtWebEngine基于Chromium构建,Chromium的部分内部对象可能采用了特殊编译策略,比如在编译单元中禁用了RTTI(-fno-rtti),导致typeid无法获取有效类型信息;另外,Chromium的某些对象可能通过自定义内存分配器创建,破坏了C++的类型识别机制。
  3. Qt封装层面的问题:QtWebEngine在封装Chromium对象时,可能存在对象生命周期管理异常,或者对部分内部对象隐藏了类型信息;也有可能Qt在编译这些模块时,针对特定对象关闭了RTTI支持,导致typeid失效。

替代解决方案

Qt的元对象系统是跨平台且可靠的类型识别方案,完全可以替代typeid的需求:

// 用Qt元对象获取类型名称,避免typeid的问题
const char* className = obj->metaObject()->className();

内容的提问来源于stack exchange,提问作者BuvinJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 11:57:13