Unsolved How to translate a function name in QJsonObject from string to function pointer?
-
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...
-
If your target object is a
QObject
, and your method is marked as slot orQ_INVOKABLE
, you can call that method by name (taken from JSON) using invokeMethod(). -
@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.
-
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;
-
@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?
-
@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 likeQ_ARG(QJsonObject, const &crobjJSON)
-
Object is needed, I don't think it will work with
nullptr
. Argument - try with justQJsonObject
, without const reference. If that still fails, maybe you need to register QJsonObject with with meta object system.Or use if-else as mentioned.
-
@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#invokeMethodWhich is why I thought the second parameter of Q_ARG had to be a string.