Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. qmetamethod, how to use after the changes?
Forum Updated to NodeBB v4.3 + New Features

qmetamethod, how to use after the changes?

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 2 Posters 1.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • TomZT Offline
    TomZT Offline
    TomZ
    wrote on last edited by
    #1

    Last year I had a lot of fun writing a scripting language and interpreter in Qt.

    There are callbacks to known QObject based tool classes and the binding is done using the meta object system from Qt.
    This worked on Qt5.
    I ported it to Qt6 November last year and still everything worked.

    Now Qt6.5 came out and everything broke. I can't figure out how to make it work again. Would love it if someone has some ideas.

    My scripting interpreter has code like this;

    auto mo = context->metaObject();
    bool found = false;
    for (int j = mo->methodOffset(); j < mo->methodCount(); ++j) {
        auto method = mo->method(j);
        if (method.name() == methodName && arguments.size() == method.parameterCount()
                && (method.methodType() == QMetaMethod::Method ||
                    method.methodType() == QMetaMethod::Slot)
                && method.access() == QMetaMethod::Public) {
            QGenericArgument qArgs[10];
            assert(arguments.size() <= 10);
            for (int a = 0; a < arguments.size(); ++a) {
                qArgs[a] = Q_ARG(QString, arguments.at(a));
            }
            QGenericReturnArgument rc;
            bool boolAnswer = false;
            int intAnswer = 0;
            QVariant varAnswer;
            if (method.returnType() == QMetaType::Bool)
                rc = Q_RETURN_ARG(bool, boolAnswer);
            else if (method.returnType() == QMetaType::Int)
                rc = Q_RETURN_ARG(int, intAnswer);
            else if (method.returnType() == QMetaType::QVariant)
                rc = Q_RETURN_ARG(QVariant, varAnswer);
            found = true;
            bool ok = method.invoke(context, Qt::DirectConnection,
                                    rc, qArgs[0], qArgs[1], qArgs[2], qArgs[3],
                    qArgs[4], qArgs[5], qArgs[6], qArgs[7], qArgs[8], qArgs[9]);
            if (!ok)
                throw SyntaxError(m_tokenizer, "Invalid arguments found");
    
    

    The important part is that the amount of arguments is not known at compile time. It comes from a script, user input. We just define they are all strings.

    The above code broke because they replaced the QGenericArgument with QMetaMethodArgument.

    So, I changed the code to follow.
    But calls to method.invoke then just crash in Qt code. This method is called deprecated. Weird, to change the arguments AND deprecated it. Not sure why its crashing, though.

    So I tried to use different overloads of invoke(), but the only option is some variadic versions. Printf style.
    Problem with that is that I have no idea how to give variable length arguments lists.

    What is the point of doing metadata programming if you have to decide at compile time what number of arguments there are?

    Frustrated and lost. Any pointers much appreciated!

    JonBJ 1 Reply Last reply
    0
    • TomZT TomZ

      @JonB I'll take a look.
      Any idea why searching for the word 'meta' did not find that one? Bug in the forums?

      • search for meta.
      • only in this category
      • in titles
      • in the last 6 months.

      Gave me 1 result, not the one you linked. Which obviously should have matched.

      TomZT Offline
      TomZT Offline
      TomZ
      wrote on last edited by TomZ
      #4

      ok, I know how to do this but its really really ugly.

      It essentially is 2 sets of 10 calls to invoke in my sourcecode and some logic to decide which of the invoke() methods I actually call.

      I have 10 calls based on the amount of arguments there are. So, Qt is awesome it deprecated the methods only to force me to write 10 of them..

      Then the invoke returns false if you pass in a default-constructed QMetaMethodReturnArgument which indicates 'void'.
      No, you have to call it without that argument if the method returns void. So... Yeah, another set of 10 calls..

      I'm hoping I missed something, because this is beneath Qt

      1 Reply Last reply
      0
      • TomZT TomZ

        Last year I had a lot of fun writing a scripting language and interpreter in Qt.

        There are callbacks to known QObject based tool classes and the binding is done using the meta object system from Qt.
        This worked on Qt5.
        I ported it to Qt6 November last year and still everything worked.

        Now Qt6.5 came out and everything broke. I can't figure out how to make it work again. Would love it if someone has some ideas.

        My scripting interpreter has code like this;

        auto mo = context->metaObject();
        bool found = false;
        for (int j = mo->methodOffset(); j < mo->methodCount(); ++j) {
            auto method = mo->method(j);
            if (method.name() == methodName && arguments.size() == method.parameterCount()
                    && (method.methodType() == QMetaMethod::Method ||
                        method.methodType() == QMetaMethod::Slot)
                    && method.access() == QMetaMethod::Public) {
                QGenericArgument qArgs[10];
                assert(arguments.size() <= 10);
                for (int a = 0; a < arguments.size(); ++a) {
                    qArgs[a] = Q_ARG(QString, arguments.at(a));
                }
                QGenericReturnArgument rc;
                bool boolAnswer = false;
                int intAnswer = 0;
                QVariant varAnswer;
                if (method.returnType() == QMetaType::Bool)
                    rc = Q_RETURN_ARG(bool, boolAnswer);
                else if (method.returnType() == QMetaType::Int)
                    rc = Q_RETURN_ARG(int, intAnswer);
                else if (method.returnType() == QMetaType::QVariant)
                    rc = Q_RETURN_ARG(QVariant, varAnswer);
                found = true;
                bool ok = method.invoke(context, Qt::DirectConnection,
                                        rc, qArgs[0], qArgs[1], qArgs[2], qArgs[3],
                        qArgs[4], qArgs[5], qArgs[6], qArgs[7], qArgs[8], qArgs[9]);
                if (!ok)
                    throw SyntaxError(m_tokenizer, "Invalid arguments found");
        
        

        The important part is that the amount of arguments is not known at compile time. It comes from a script, user input. We just define they are all strings.

        The above code broke because they replaced the QGenericArgument with QMetaMethodArgument.

        So, I changed the code to follow.
        But calls to method.invoke then just crash in Qt code. This method is called deprecated. Weird, to change the arguments AND deprecated it. Not sure why its crashing, though.

        So I tried to use different overloads of invoke(), but the only option is some variadic versions. Printf style.
        Problem with that is that I have no idea how to give variable length arguments lists.

        What is the point of doing metadata programming if you have to decide at compile time what number of arguments there are?

        Frustrated and lost. Any pointers much appreciated!

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #2

        @TomZ I don't know, but is https://forum.qt.io/topic/144576/passing-variable-length-args-in-container-for-qmetaobject-invokemethod of any interest to you?

        TomZT 1 Reply Last reply
        0
        • JonBJ JonB

          @TomZ I don't know, but is https://forum.qt.io/topic/144576/passing-variable-length-args-in-container-for-qmetaobject-invokemethod of any interest to you?

          TomZT Offline
          TomZT Offline
          TomZ
          wrote on last edited by
          #3

          @JonB I'll take a look.
          Any idea why searching for the word 'meta' did not find that one? Bug in the forums?

          • search for meta.
          • only in this category
          • in titles
          • in the last 6 months.

          Gave me 1 result, not the one you linked. Which obviously should have matched.

          TomZT 1 Reply Last reply
          0
          • TomZT TomZ referenced this topic on
          • TomZT TomZ

            @JonB I'll take a look.
            Any idea why searching for the word 'meta' did not find that one? Bug in the forums?

            • search for meta.
            • only in this category
            • in titles
            • in the last 6 months.

            Gave me 1 result, not the one you linked. Which obviously should have matched.

            TomZT Offline
            TomZT Offline
            TomZ
            wrote on last edited by TomZ
            #4

            ok, I know how to do this but its really really ugly.

            It essentially is 2 sets of 10 calls to invoke in my sourcecode and some logic to decide which of the invoke() methods I actually call.

            I have 10 calls based on the amount of arguments there are. So, Qt is awesome it deprecated the methods only to force me to write 10 of them..

            Then the invoke returns false if you pass in a default-constructed QMetaMethodReturnArgument which indicates 'void'.
            No, you have to call it without that argument if the method returns void. So... Yeah, another set of 10 calls..

            I'm hoping I missed something, because this is beneath Qt

            1 Reply Last reply
            0
            • TomZT TomZ has marked this topic as solved on

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved