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. How to translate a function name in QJsonObject from string to function pointer?
Forum Updated to NodeBB v4.3 + New Features

How to translate a function name in QJsonObject from string to function pointer?

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 551 Views 2 Watching
  • 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.
  • S Offline
    S Offline
    SPlatten
    wrote on 2 Jan 2021, 10:39 last edited by
    #1

    I have a QJsonObject containing:

    decoder: "decoderFn"
    

    To extract the function name as a string:

    QJsonObject::iterator itrDecoder = objDecoder.find(clsJSON::mscszDecoder);
    
    if ( itrDecoder == objDecoder.end() ) {
        continue;
    }
    QString strDecoder = itrDecoder.value().toString();
    

    Can I translate strDecoder to a function pointer or do I need to change the string contents to a full prototype of the function?

    And use eval? Will try out whilst waiting for a comment / answer...

    Kind Regards,
    Sy

    1 Reply Last reply
    0
    • S Offline
      S Offline
      sierdzio
      Moderators
      wrote on 2 Jan 2021, 10:45 last edited by
      #2

      If your target object is a QObject, and your method is marked as slot or Q_INVOKABLE, you can call that method by name (taken from JSON) using invokeMethod().

      (Z(:^

      S 1 Reply Last reply 2 Jan 2021, 10:48
      1
      • S sierdzio
        2 Jan 2021, 10:45

        If your target object is a QObject, and your method is marked as slot or Q_INVOKABLE, you can call that method by name (taken from JSON) using invokeMethod().

        S Offline
        S Offline
        SPlatten
        wrote on 2 Jan 2021, 10:48 last edited by SPlatten 1 Feb 2021, 10:50
        #3

        @sierdzio , thank you, can you show an example? My functions in the JSON aren't part of a class, something like:

        bool blnDecodeHeartbeat(const QJsonObject& crobjJSON) {
            clsModule* pModule = pDecodeModuleAndPort(crobjJSON);
            if ( pModule != nullptr ) {
                if ( pModule->blnIsMsgSndrSet() != true ) {
                    QJsonObject::const_iterator citrFound = crobjJSON.find(clsJSON::mscszPort);
        
                    if ( citrFound == crobjJSON.end() ) {
            //No port in message, cannot set port, abort decode!
                        return false;
                    }
                }            
                pModule->updateHearbeat();
            //Extract the message type from the message
                clsJSON::sendAck(crobjJSON);
                return true;
            }
            return false;
        }
        

        If wrapping them up in a class would help, I can do that...can you help with an example? All the functions I want to use like this will have the same prototype, I mean same return and parameters.

        Kind Regards,
        Sy

        S 1 Reply Last reply 2 Jan 2021, 10:58
        0
        • S SPlatten
          2 Jan 2021, 10:48

          @sierdzio , thank you, can you show an example? My functions in the JSON aren't part of a class, something like:

          bool blnDecodeHeartbeat(const QJsonObject& crobjJSON) {
              clsModule* pModule = pDecodeModuleAndPort(crobjJSON);
              if ( pModule != nullptr ) {
                  if ( pModule->blnIsMsgSndrSet() != true ) {
                      QJsonObject::const_iterator citrFound = crobjJSON.find(clsJSON::mscszPort);
          
                      if ( citrFound == crobjJSON.end() ) {
              //No port in message, cannot set port, abort decode!
                          return false;
                      }
                  }            
                  pModule->updateHearbeat();
              //Extract the message type from the message
                  clsJSON::sendAck(crobjJSON);
                  return true;
              }
              return false;
          }
          

          If wrapping them up in a class would help, I can do that...can you help with an example? All the functions I want to use like this will have the same prototype, I mean same return and parameters.

          S Offline
          S Offline
          sierdzio
          Moderators
          wrote on 2 Jan 2021, 10:58 last edited by sierdzio 1 Feb 2021, 10:58
          #4

          Hm in that case I'd rather do an if-else cascade and call proper function depending on JSON data.

          Anyway, coming back to invokeMethod() idea:

          class MyClass : public QObject
          {
            Q_OBJECT
          
          public:
            Q_INVOKABLE int decoderFn(int something);
          };
          
          // And now, in your JSON parser:
          MyClass myObject = ...;
          QString strDecoder = itrDecoder.value().toString();
          int returnValue = 0;
          bool isOk = QMetaObject()::invokeMethod(
            myObject, strDecoder.constData(),
            Qt::DirectConnection,
            Q_RETURN_ARG(int, returnValue), Q_ARG(int, 123));
          
          qDebug() << "Result is:" << returnValue << "is ok?" << isOk;
          

          (Z(:^

          S 1 Reply Last reply 2 Jan 2021, 11:01
          1
          • S sierdzio
            2 Jan 2021, 10:58

            Hm in that case I'd rather do an if-else cascade and call proper function depending on JSON data.

            Anyway, coming back to invokeMethod() idea:

            class MyClass : public QObject
            {
              Q_OBJECT
            
            public:
              Q_INVOKABLE int decoderFn(int something);
            };
            
            // And now, in your JSON parser:
            MyClass myObject = ...;
            QString strDecoder = itrDecoder.value().toString();
            int returnValue = 0;
            bool isOk = QMetaObject()::invokeMethod(
              myObject, strDecoder.constData(),
              Qt::DirectConnection,
              Q_RETURN_ARG(int, returnValue), Q_ARG(int, 123));
            
            qDebug() << "Result is:" << returnValue << "is ok?" << isOk;
            
            S Offline
            S Offline
            SPlatten
            wrote on 2 Jan 2021, 11:01 last edited by SPlatten 1 Feb 2021, 11:02
            #5

            @sierdzio , I was trying:

                    QMetaObject::invokeMethod(nullptr, cpszDecode, Qt::DirectConnection
                                             ,Q_RETURN_ARG(bool, blnRet)
                                             ,Q_ARG(const QJsonObject&, "crobjJSON"));
            

            With the first parameter to see if it would work but I get:

            no matching constructor for invalidation of 'QArgument<const QJsonObject&>'
            

            If I move my decode functions into a class and pass the type to the first parameter how do I satisfy the argument type?

            Kind Regards,
            Sy

            KroMignonK 1 Reply Last reply 2 Jan 2021, 11:10
            0
            • S SPlatten
              2 Jan 2021, 11:01

              @sierdzio , I was trying:

                      QMetaObject::invokeMethod(nullptr, cpszDecode, Qt::DirectConnection
                                               ,Q_RETURN_ARG(bool, blnRet)
                                               ,Q_ARG(const QJsonObject&, "crobjJSON"));
              

              With the first parameter to see if it would work but I get:

              no matching constructor for invalidation of 'QArgument<const QJsonObject&>'
              

              If I move my decode functions into a class and pass the type to the first parameter how do I satisfy the argument type?

              KroMignonK Offline
              KroMignonK Offline
              KroMignon
              wrote on 2 Jan 2021, 11:10 last edited by
              #6

              @SPlatten said in How to translate a function name in QJsonObject from string to function pointer?:

              no matching constructor for invalidation of 'QArgument<const QJsonObject&>'

              First, "crobjJSON" is a string not a QJsonObject!

              Second, Q_ARG() should be something like Q_ARG(QJsonObject, const &crobjJSON)

              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

              S 1 Reply Last reply 2 Jan 2021, 11:17
              1
              • S Offline
                S Offline
                sierdzio
                Moderators
                wrote on 2 Jan 2021, 11:10 last edited by
                #7

                Object is needed, I don't think it will work with nullptr. Argument - try with just QJsonObject, without const reference. If that still fails, maybe you need to register QJsonObject with with meta object system.

                Or use if-else as mentioned.

                (Z(:^

                1 Reply Last reply
                0
                • KroMignonK KroMignon
                  2 Jan 2021, 11:10

                  @SPlatten said in How to translate a function name in QJsonObject from string to function pointer?:

                  no matching constructor for invalidation of 'QArgument<const QJsonObject&>'

                  First, "crobjJSON" is a string not a QJsonObject!

                  Second, Q_ARG() should be something like Q_ARG(QJsonObject, const &crobjJSON)

                  S Offline
                  S Offline
                  SPlatten
                  wrote on 2 Jan 2021, 11:17 last edited by
                  #8

                  @KroMignon I was using the example:

                  QString retVal;
                  QMetaObject::invokeMethod(obj, "compute", Qt::DirectConnection,
                                            Q_RETURN_ARG(QString, retVal),
                                            Q_ARG(QString, "sqrt"),
                                            Q_ARG(int, 42),
                                            Q_ARG(double, 9.7));
                  

                  on:
                  https://doc.qt.io/qt-5/qmetaobject.html#invokeMethod

                  Which is why I thought the second parameter of Q_ARG had to be a string.

                  Kind Regards,
                  Sy

                  1 Reply Last reply
                  0

                  1/8

                  2 Jan 2021, 10:39

                  • Login

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