QML和JS引擎的關系以及調用c++函數的原理


首先推薦幾篇博客

1.深入解析QML引擎, 第1部分:QML文件加載

https://www.cnblogs.com/wzxNote/p/10569535.html

2.深入解析QML引擎, 第2部分: 綁定(Bindings)

https://www.cnblogs.com/wzxNote/p/10569542.html

3.深入解析QML引擎, 第3部分: 綁定類型

https://www.cnblogs.com/wzxNote/p/10569547.html

4.深入解析QML引擎, 第4部分: 自定義解析器

https://www.cnblogs.com/wzxNote/p/10569554.html

5.QML引擎的演進,第一部分

https://blog.qt.io/cn/2013/04/18/evolution-of-the-qml-engine-part-1/

這四篇博文由淺入深的講述了QML引擎的實現機制。

1.QML文件的加載過程涉及到QML文件的解析,js代碼的解釋;

2.綁定講解了QML的屬性綁定,通過VME模塊創建的指令.生成一個QQmlBinding對象,傳入js函數,vme再把傳入的函數生成一個v8:Function函數(翻譯成二進制的機器碼)。通過運行編譯后的V8::Function代碼來對綁定進行求值,再由V8引擎通過Qt里的包裹類來訪問對象和屬性,然后將求的值賦給目標屬性。

3.因為QV8Bindings把QML文件中所有的綁定組織在一起,所以可以花費更少的內存,並只執行一次編譯。

歸納起來,有3個綁定類型,都是從QQmlAbstractBinding繼承:

1). QV4Bindings::Binding

2). QV8Bindings::Binding

3). QQmlBinding

QV4Bindings是最快的,因為其使用了自定義的字節碼引擎。QV8Bindings和QQmlBinding都是使用V8 JS引擎執行,但QV8Bindings將所有的綁定組織在一起,一次性編譯,然而QQmlBindings會在每個QML組件實例化過程中一個一個地進行編譯。

4.多個對象模型

當前的QML引擎使用V8 JavaScript引擎來執行屬性綁定。每個QML項內部有幾個不同的表示。一個面向V8(使用公開的V8 API),一個面向QML引擎,還有一個作為QObject暴露給原生Qt。這里的問題是需要QML引擎來同步這些不同的表示,導致了大量的中間代碼和相當高的內存消耗來維持這些不同的表示。

QML調用js函數的調用堆棧如下:

QML調用C++函數的調用堆棧如下:

person類(js調用的c++函數所在的類)的函數最后的調用過程為

void Person::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
    if (_c == QMetaObject::InvokeMetaMethod) {
        auto *_t = static_cast<Person *>(_o);
        Q_UNUSED(_t)
        switch (_id) {
        case 0: _t->walk(); break;
        case 1: { bool _r = _t->eat((*reinterpret_cast< const QString(*)>(_a[1])));
            if (_a[0]) *reinterpret_cast< bool*>(_a[0]) = std::move(_r); }  break;
        default: ;
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM