Call invokeMethod passing argument by (no const) reference - Q_ARG(Type&, value)
-
Dear all,
just a simple question: suppose having a slot defined in this way:
class Sample : public QObject { Q_OBJECT ... public slots: int populateBytes(QByteArray& bytes); ... }
I'm calling that method using
QMetaObject::invokeMethod()
cause its object instance is living in another thread.
I'm using aBlockingQueuedConnection
, cause I need to wait method results; the calling function is similar to this one:void testFunction() { int result; QByteArray testBytes; QMetaObject::invokeMethod( &objInstance, "populateBytes", Qt::BlockingQueuedConnection, Q_RETURN_ARG(result, int), Q_ARG(QByteArray&, testBytes) // <--- is it correct??? ); return result; }
From Q_ARG documentation, I expect that isn't possible passing a parameter using a no const value. Instead it seems working.
Going a bit deeper, I see that
Q_ARG
is define as follow:
#define Q_ARG(type, data) QArgument<type >(#type, data)
where:
template <class T> class QArgument: public QGenericArgument { public: inline QArgument(const char *aName, const T &aData) : QGenericArgument(aName, static_cast<const void *>(&aData)) // <--- const void* !!! {} }; template <class T> class QArgument<T &>: public QGenericArgument { public: inline QArgument(const char *aName, T &aData) : QGenericArgument(aName, static_cast<const void *>(&aData)) // <--- const void* !!! {} };
So, in both solution,
aData
will be use as aconst void*
parameter.Am I "forcing" some const value to be no const?
In another way, is it safe passing a variable by reference, instead of const reference in aQMetaObject::invokeMethod(..., Q_ARG(Type&, value),..)
call?I'm using Qt 6.2.7
Thanks all.
-
You're aware that QMetaObject::invokeMethod() does not block so you can't return anything if it is async. Again: a slot does not return anything - your design is broken, fix it.
-
A slot can never have a (non-const) reference since a slot might be executed asynchronously.
A slot is doing something but never bringing something back so your populateBytes() is not a slot at all. -
Generally I'm agree to you @Christian-Ehrlicher.
But, in case I'm using that slot only via
Qt::DirectConnection
orQt::BlockingQueueConnection
, is not possible using a (non-const) reference?From some tests, I see that
testBytes
is correctly populated usingQt::BlockingQueueConnection
, but I'm not sure if this is an exceptional case or not. -
Or, maybe, a better solution is passing a
QByteArray*
: in this case, it's my responsibity to assure that allocate space is keeping available in async call.. -
You're aware that QMetaObject::invokeMethod() does not block so you can't return anything if it is async. Again: a slot does not return anything - your design is broken, fix it.
-
@Christian-Ehrlicher Ok, i'm going to use a signal/slot like solution.
It's both more clean and safety.
-