I'm trying to hack with Qt's signals and slots, and I ran into an issue where QMetaType::invokeMethod won't properly pass pointer arguments to the slot being called.
call(QObject *receiver, const char *slot, const QList<QGenericArgument> &args)
{
const QMetaObject *meta = receiver->metaObject();
bool success = meta->invokeMethod(receiver, slot,
args.value(0, QGenericArgument()),
args.value(1, QGenericArgument()),
args.value(2, QGenericArgument()),
...
args.value(9, QGenericArgument()));
}
Then I call it the following way:
MyReceiver *receiver;
MyObject *myObject;
call(receiver, "mySlot", QList<QGenericArgument>() << Q_ARG(MyObject *, myObject));
Where class MyObject : public QObject { ... }
. I also do Q_DECLARE_METATYPE(MyObject *)
and qRegisterMetaType<MyObject *>("MyObject *")
What happens is that the slot on the receiver is being invoked, but with the value of the argument is always 0
no matter what I pass to the call(...)
as Q_ARG
Out of curiosity I looked into the auto-generated MOC file of the receiver, and found that the slots are invoked with the following code:
void MyReceiver::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
MyReceiver *_t = static_cast<MyReceiver *>(_o);
switch (_id) {
case 0: _t->mySlot((*reinterpret_cast< MyObject*(*)>(_a[1]))); break;
default: ;
}
}
}
Turns out that the value of _a[1]
bears proper address of MyObject *
. But the reinterpret_cast
turns it into 0
.
Now I have the following questions:
1) How to programmatically invoke a slot and make sure that the pointer arguments are properly passed to the slot?
2) What does this *reinterpret_cast< MyObject*(*)>(_a[1])
mean? What the extra parentheses (*)
mean, and how to interpret this piece of code?