Ale*_*kiy 5 c++ qt exception qtscript
我在我的应用程序中使用Qt脚本引擎作为用户访问其功能的替代方法.因此,我将一些C++类导出到Qt ScriptEngine,它将作为应用程序的接口.问题是,这些C++类可以抛出异常.
我有一个"ScriptInterface"类在自己的线程上运行,侦听处理脚本的请求.因此,当我评估用户的脚本时,我有一个try/catch块来处理异常,并将错误打印到应用程序中的控制台.
...
try {
m_engine->evaluate(script, name);
}
catch (Exception const& e) {
// deal with it
}
catch (...) {
// scary message
}
Run Code Online (Sandbox Code Playgroud)
这在windows中完美运行...但在linux中不起作用 - 程序终止于此消息:
terminate called after throwing an instance of 'Basilisk::InvalidArgumentException'
what(): N8Basilisk24InvalidArgumentExceptionE
Aborted
Run Code Online (Sandbox Code Playgroud)
我有一种预感,因为异常冒泡到事件处理程序(因为脚本引擎使用信号来调用导出的类中的函数),所以我重新实现了QApplication :: notify,以处理那里的异常,但它们不是'抓住了.
我的问题是,我做了一些根本错误的事情吗?另外,作为替代方案,是否可以从我的C++类中显式抛出脚本异常?
提前致谢
编辑:修改说明以包含catch(...)语句.
更新(解决方案):我通过遵循类似于接受的答案中概述的策略来"修复"此问题.虽然我还没有找到为什么异常不会被linux捕获的原因(我现在怀疑是m_engine-> evaluate在linux上产生一个单独的线程),但我已经开始使用预期的异常抛出方式在Qt Scripts中,就是这样QScriptContext::throwError().
如果我的函数看起来像这样:(随机例子)
void SomeClass::doStuff(unsigned int argument) {
if (argument != 42) {
throw InvalidArgumentException(
"Not the answer to Life, the Universe and Everything.");
}
// function that is not part of the scripting environment,
// and can throw a C++ exception
dangerousFunction(argument);
}
Run Code Online (Sandbox Code Playgroud)
现在是这样的:(特别注意返回类型)
QScriptValue SomeClass::doStuff(unsigned int argument) {
if (argument != 42) {
// assuming m_engine points to an instance of
// QScriptEngine that will be calling this function
return m_engine->currentContext()->throwError(QScriptContext::SyntaxError,
"Not the answer to Life, the Universe and Everything.");
}
try {
// function that is not part of the scripting environment,
// and can throw a C++ exception
dangerousFunction(argument);
} catch (ExpectedException const& e) {
return m_engine->currentContext()->throwError(QScriptContext::UnknownError,
e.message());
}
// if no errors returned, return an invalid QScriptValue,
// equivalent to void
return QScriptValue();
}
Run Code Online (Sandbox Code Playgroud)
那么在哪里处理这些脚本错误呢?在调用QScriptEngine::evaluate()你之后可以检查是否有任何未捕获的异常,用QScriptEngine::hasUncaughtException(),获取错误对象uncaughtException(),现在你在错误发生的脚本中有消息,跟踪和行号!
希望这可以帮助别人!
当我尝试使用 SWIG 和 Python 来包装 C++ 库时,我遇到了类似的问题。最终发生的事情是,我为所有包装的类创建了一个存根,这些类捕获了异常并静静地失败了。幸运的是,我拥有只传递容器类和状态模式对象的包装功能,因此我可以轻松检查是否有问题。我可以给你同样的建议吗?
是的,如果您授予脚本引擎访问异常工厂(一个唯一目的是抛出 C++ 异常的类)的权限,脚本引擎很可能会抛出 C++ 异常。