在做回调的过程中遇到这个问题,但是有的函数就成功了,有的不行,怎么改都是提示QMetaObject::invokeMethod: No such method
QObject* obj = temp.caller;
QByteArray slotName = temp.slotName;
if(obj != NULL && !slotName.isEmpty()){
bool ok;//记录调用槽是否成功
int parameterCount = obj->metaObject()->method(obj->metaObject()->indexOfMethod(slotName)).parameterTypes().length();
QRegExp reg("^[^(]+");
reg.indexIn (slotName);
slotName = reg.cap (0).toLatin1 ();
if(parameterCount==0){//如果形参个数为0个
ok = QMetaObject::invokeMethod(obj, slotName);
}
else if(parameterCount==1){
ok = QMetaObject::invokeMethod(obj, slotName, Q_ARG(QByteArray, cmdData));
}
else if(parameterCount==2){
ok = QMetaObject::invokeMethod(obj, slotName, Q_ARG(qint64, seq), Q_ARG(QByteArray, cmdData));
}
else{
ok = false;
}
if(!ok){
qDebug()<<"MyHttpRequest:调用槽"+slotName+"失败";
}
}
最后查找了qt的源码部分看看为什么提示那个错误
qt源码:
bool QMetaObject::invokeMethod(QObject *obj,
const char *member,
Qt::ConnectionType type,
QGenericReturnArgument ret,
QGenericArgument val0,
QGenericArgument val1,
QGenericArgument val2,
QGenericArgument val3,
QGenericArgument val4,
QGenericArgument val5,
QGenericArgument val6,
QGenericArgument val7,
QGenericArgument val8,
QGenericArgument val9)
{
if (!obj)
return false;
QVarLengthArray<char, 512> sig;
int len = qstrlen(member);
if (len <= 0)
return false;
sig.append(member, len);
sig.append('(');
const char *typeNames[] = {ret.name(), val0.name(), val1.name(), val2.name(), val3.name(),
val4.name(), val5.name(), val6.name(), val7.name(), val8.name(),
val9.name()};
int paramCount;
for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
len = qstrlen(typeNames[paramCount]);
if (len <= 0)
break;
sig.append(typeNames[paramCount], len);
sig.append(',');
}
if (paramCount == 1)
sig.append(')'); // no parameters
else
sig[sig.size() - 1] = ')';
sig.append('\0');
const QMetaObject *meta = obj->metaObject();
int idx = meta->indexOfMethod(sig.constData());
if (idx < 0) {
QByteArray norm = QMetaObject::normalizedSignature(sig.constData());
idx = meta->indexOfMethod(norm.constData());
}
if (idx < 0 || idx >= meta->methodCount()) {
qWarning("QMetaObject::invokeMethod: No such method %s::%s",
meta->className(), sig.constData());
return false;
}
QMetaMethod method = meta->method(idx);
return method.invoke(obj, type, ret,
val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
}
从中知道是因为index获取的不对,结果在我的代码里打印了一下,确实是index是-1,于是网上各种搜,怎么解决indexOfMethod()的返回值问题,后来找到一篇博文,
http://blog.csdn.net/gyh198/article/details/7837565,关于qt内部机制及逆向,找到了一部分代码
- int idx = obj->metaObject()->indexOfMethod(sig.constData());
- if (idx < 0) {
- QByteArray norm = QMetaObject::normalizedSignature(sig.constData());
- idx = obj->metaObject()->indexOfMethod(norm.constData());
- }
- if (idx < 0)
- return false;
修改后的我的代码:
QObject* obj = temp.caller;
QByteArray slotName = temp.slotName;
if(obj != NULL && !slotName.isEmpty()){
bool ok;//记录调用槽是否成功
int idx = obj->metaObject()->indexOfMethod(slotName.constData());
if (idx < 0)
{
QByteArray norm = QMetaObject::normalizedSignature(slotName.constData());
idx = obj->metaObject()->indexOfMethod(norm.constData());
}
int parameterCount = obj->metaObject()->method(idx).parameterTypes().length();
QRegExp reg("^[^(]+");
reg.indexIn (slotName);
slotName = reg.cap (0).toLatin1 ();
if(parameterCount==0){
ok = QMetaObject::invokeMethod(obj, slotName);
}
else if(parameterCount==1){
ok = QMetaObject::invokeMethod(obj, slotName, Q_ARG(QByteArray, cmdData));
}
else if(parameterCount==2){
ok = QMetaObject::invokeMethod(obj, slotName, Q_ARG(qint64, seq), Q_ARG(QByteArray, cmdData));
}
else{
ok = false;
}
if(!ok){
qDebug()<<"MyHttpRequest:调用槽"+slotName+"失败";
}
}
通过这种方法,解决了返回值的问题,结果一试,真的,心情不知道怎么表达了,赶紧分享一下,希望对你们有帮助,有问题还可以联系我qq:1256622929