Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-71546

QV4::FunctionObject::isBinding() should become public API

    XMLWordPrintable

Details

    • Suggestion
    • Resolution: Won't Do
    • Not Evaluated
    • None
    • 5.12.0 Beta 3
    • None
    • Qt 5.12x
      Android
      macOS, iOS
      or any other with -fvisibility-inlines-hidden cflag

    • Android, iOS/tvOS/watchOS, macOS

    Description

      The QV4::FunctionObject::isBinding() function is declared as inline function in 5.12, and can not be linked properly any more.

       

      The windows (msvc) or Qt < 5.12 works without this issue.

       

      In 5.12, the compiler will report the following error:

      ..\..\..\Qt\5.12.0\android_armv7\include\QtQml\5.12.0\QtQml\private/qqmlbuiltinfunctions_p.h:0: error: undefined reference to 'QV4::QQmlBindingFunction::static_vtbl'
      

      It appears -fvisibility-inlines-hidden will cause inline function not exported normally, and need to be inline when compiling. It is fine as long as the inline function does not reference other non-exported function. But in QV4::FunctionObject::isBinding() case, it will cause the linking error, and there is no way to fix the issue without heavy hack. e.g.

      static bool isBinding(QObject* obj, QV4::FunctionObject* func)
      {
      #if defined(QT_STATIC) || QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
          return func && func->isBinding();
      #else
          // due to QV4::FunctionObject::isBinding() become inline function and not exported from shared library
          // we can't get it linked properly any more, thus need to reproduce the function here
          // the gotcha is to get vtable of binding and compare it with func->vtable()
          static const void* _vtable_binding = nullptr;
          if (!_vtable_binding) {
              auto engine = qmlEngine(obj);
              auto expr = engine->evaluate("Qt.binding(function() { return Qt.application.active; })");
              auto& value = *QJSValuePrivate::getValue(&expr);
              auto binding = value.as<QV4::FunctionObject>();
              _vtable_binding = binding->vtable();
          }
          return func && func->vtable() == _vtable_binding;
      #endif
      }
      

      It would be great if there is some kind of helper function for external linking, like

      bool qt_FunctionObject_isBinding(QV4::FunctionObject* func);
      

       

      or revert the function to non-inline.

       

       

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qt.team.quick.subscriptions Qt Quick and Widgets Team
            steve.k.chiu Steve K. Chiu
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes