qmetamethod, how to use after the changes?
-
Last year I had a lot of fun writing a scripting language and interpreter in Qt.
There are callbacks to known QObject based tool classes and the binding is done using the meta object system from Qt.
This worked on Qt5.
I ported it to Qt6 November last year and still everything worked.Now Qt6.5 came out and everything broke. I can't figure out how to make it work again. Would love it if someone has some ideas.
My scripting interpreter has code like this;
auto mo = context->metaObject(); bool found = false; for (int j = mo->methodOffset(); j < mo->methodCount(); ++j) { auto method = mo->method(j); if (method.name() == methodName && arguments.size() == method.parameterCount() && (method.methodType() == QMetaMethod::Method || method.methodType() == QMetaMethod::Slot) && method.access() == QMetaMethod::Public) { QGenericArgument qArgs[10]; assert(arguments.size() <= 10); for (int a = 0; a < arguments.size(); ++a) { qArgs[a] = Q_ARG(QString, arguments.at(a)); } QGenericReturnArgument rc; bool boolAnswer = false; int intAnswer = 0; QVariant varAnswer; if (method.returnType() == QMetaType::Bool) rc = Q_RETURN_ARG(bool, boolAnswer); else if (method.returnType() == QMetaType::Int) rc = Q_RETURN_ARG(int, intAnswer); else if (method.returnType() == QMetaType::QVariant) rc = Q_RETURN_ARG(QVariant, varAnswer); found = true; bool ok = method.invoke(context, Qt::DirectConnection, rc, qArgs[0], qArgs[1], qArgs[2], qArgs[3], qArgs[4], qArgs[5], qArgs[6], qArgs[7], qArgs[8], qArgs[9]); if (!ok) throw SyntaxError(m_tokenizer, "Invalid arguments found");
The important part is that the amount of arguments is not known at compile time. It comes from a script, user input. We just define they are all strings.
The above code broke because they replaced the QGenericArgument with QMetaMethodArgument.
So, I changed the code to follow.
But calls to method.invoke then just crash in Qt code. This method is called deprecated. Weird, to change the arguments AND deprecated it. Not sure why its crashing, though.So I tried to use different overloads of invoke(), but the only option is some variadic versions. Printf style.
Problem with that is that I have no idea how to give variable length arguments lists.What is the point of doing metadata programming if you have to decide at compile time what number of arguments there are?
Frustrated and lost. Any pointers much appreciated!
-
@JonB I'll take a look.
Any idea why searching for the word 'meta' did not find that one? Bug in the forums?- search for meta.
- only in this category
- in titles
- in the last 6 months.
Gave me 1 result, not the one you linked. Which obviously should have matched.
ok, I know how to do this but its really really ugly.
It essentially is 2 sets of 10 calls to invoke in my sourcecode and some logic to decide which of the invoke() methods I actually call.
I have 10 calls based on the amount of arguments there are. So, Qt is awesome it deprecated the methods only to force me to write 10 of them..
Then the invoke returns false if you pass in a default-constructed QMetaMethodReturnArgument which indicates 'void'.
No, you have to call it without that argument if the method returns void. So... Yeah, another set of 10 calls..I'm hoping I missed something, because this is beneath Qt
-
Last year I had a lot of fun writing a scripting language and interpreter in Qt.
There are callbacks to known QObject based tool classes and the binding is done using the meta object system from Qt.
This worked on Qt5.
I ported it to Qt6 November last year and still everything worked.Now Qt6.5 came out and everything broke. I can't figure out how to make it work again. Would love it if someone has some ideas.
My scripting interpreter has code like this;
auto mo = context->metaObject(); bool found = false; for (int j = mo->methodOffset(); j < mo->methodCount(); ++j) { auto method = mo->method(j); if (method.name() == methodName && arguments.size() == method.parameterCount() && (method.methodType() == QMetaMethod::Method || method.methodType() == QMetaMethod::Slot) && method.access() == QMetaMethod::Public) { QGenericArgument qArgs[10]; assert(arguments.size() <= 10); for (int a = 0; a < arguments.size(); ++a) { qArgs[a] = Q_ARG(QString, arguments.at(a)); } QGenericReturnArgument rc; bool boolAnswer = false; int intAnswer = 0; QVariant varAnswer; if (method.returnType() == QMetaType::Bool) rc = Q_RETURN_ARG(bool, boolAnswer); else if (method.returnType() == QMetaType::Int) rc = Q_RETURN_ARG(int, intAnswer); else if (method.returnType() == QMetaType::QVariant) rc = Q_RETURN_ARG(QVariant, varAnswer); found = true; bool ok = method.invoke(context, Qt::DirectConnection, rc, qArgs[0], qArgs[1], qArgs[2], qArgs[3], qArgs[4], qArgs[5], qArgs[6], qArgs[7], qArgs[8], qArgs[9]); if (!ok) throw SyntaxError(m_tokenizer, "Invalid arguments found");
The important part is that the amount of arguments is not known at compile time. It comes from a script, user input. We just define they are all strings.
The above code broke because they replaced the QGenericArgument with QMetaMethodArgument.
So, I changed the code to follow.
But calls to method.invoke then just crash in Qt code. This method is called deprecated. Weird, to change the arguments AND deprecated it. Not sure why its crashing, though.So I tried to use different overloads of invoke(), but the only option is some variadic versions. Printf style.
Problem with that is that I have no idea how to give variable length arguments lists.What is the point of doing metadata programming if you have to decide at compile time what number of arguments there are?
Frustrated and lost. Any pointers much appreciated!
-
@TomZ I don't know, but is https://forum.qt.io/topic/144576/passing-variable-length-args-in-container-for-qmetaobject-invokemethod of any interest to you?
@JonB I'll take a look.
Any idea why searching for the word 'meta' did not find that one? Bug in the forums?- search for meta.
- only in this category
- in titles
- in the last 6 months.
Gave me 1 result, not the one you linked. Which obviously should have matched.
-
T TomZ referenced this topic on
-
@JonB I'll take a look.
Any idea why searching for the word 'meta' did not find that one? Bug in the forums?- search for meta.
- only in this category
- in titles
- in the last 6 months.
Gave me 1 result, not the one you linked. Which obviously should have matched.
ok, I know how to do this but its really really ugly.
It essentially is 2 sets of 10 calls to invoke in my sourcecode and some logic to decide which of the invoke() methods I actually call.
I have 10 calls based on the amount of arguments there are. So, Qt is awesome it deprecated the methods only to force me to write 10 of them..
Then the invoke returns false if you pass in a default-constructed QMetaMethodReturnArgument which indicates 'void'.
No, you have to call it without that argument if the method returns void. So... Yeah, another set of 10 calls..I'm hoping I missed something, because this is beneath Qt
-
T TomZ has marked this topic as solved on