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 *")

何が起こるかというと、レシーバーのスロットが呼び出されていますが、引数の値は、 as0に何を渡しても常に重要です。call(...)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 は、私のポインターへのポインターを作成し、前者を保存するだけです。Q_ARG にラップされた値が既に範囲外である場合、関数が後でスロットを呼び出すことを意図した呼び出しのcall一部であることは言及しませんでした。Task基本的に、Q_ARG は引数オブジェクトへの弱参照のみを維持します。

于 2012-12-04T17:18:50.413 に答える