4

我试图破解 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 *")

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

出于好奇,我查看了接收器自动生成的 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])意思?额外的括号是什么(*)意思,以及如何解释这段代码?

4

1 回答 1

0

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

于 2012-12-04T17:18:50.413 回答