Qt-调用将自定义指针作为参数的槽



我试图破解Qt的信号和插槽,但我遇到了一个问题,QMetaType::invokeMethod无法正确地将指针参数传递到被调用的插槽。

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()));
}

然后我用下面的方式来称呼它:

MyReceiver *receiver;
MyObject *myObject;
call(receiver, "mySlot", QList<QGenericArgument>() << Q_ARG(MyObject *, myObject));

其中class MyObject : public QObject { ... }。我也做Q_DECLARE_METATYPE(MyObject *)qRegisterMetaType<MyObject *>("MyObject *")

发生的情况是,正在调用接收器上的插槽,但无论我将什么作为Q_ARG传递给call(...),参数的值始终为0

出于好奇,我查看了接收器的自动生成的MOC文件,发现插槽是用以下代码调用的:

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: ;
}
}
}

结果表明,_a[1]的值带有MyObject *的正确地址。但reinterpret_cast将其转换为0

现在我有以下问题:

1) 如何以编程方式调用插槽并确保指针参数正确传递到插槽?2) 这个*reinterpret_cast< MyObject*(*)>(_a[1])是什么意思?额外的括号(*)是什么意思,以及如何解释这段代码?

好吧,我想我明白为什么它不起作用了。。。Q_ARG只会创建一个指向我的指针的指针并存储前者。我没有提到call函数是Task调用的一部分,该调用旨在稍后调用插槽——当封装到Q_ARG中的值已经超出范围时。基本上,Q_ARG只维护对参数对象的弱引用。

最新更新