gpt4 book ai didi

c++ - 处理导出到 QtScript 的函数中抛出的 C++ 异常

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:36:59 27 4
gpt4 key购买 nike

我在我的应用程序中使用 Qt 脚本引擎作为用户访问其功能的替代方式。因此,我将一些 C++ 类导出到 Qt ScriptEngine,它将作为应用程序的接口(interface)。问题是,这些 C++ 类会抛出异常。

我有一个“ScriptInterface”类在它自己的线程上运行,监听处理脚本的请求。因此,当我评估用户的脚本时,我在它周围有一个 try/catch block 来处理异常,并将错误打印到应用程序的控制台。

...
try {
m_engine->evaluate(script, name);
}
catch (Exception const& e) {
// deal with it
}
catch (...) {
// scary message
}

这在 Windows 中完美运行...但在 Linux 中不起作用 - 程序终止并显示以下消息:

terminate called after throwing an instance of 'Basilisk::InvalidArgumentException'
what(): N8Basilisk24InvalidArgumentExceptionE
Aborted

我有一种预感,这是因为异常冒泡到事件处理程序(因为脚本引擎使用信号来调用我导出的类中的函数),所以我重新实现了 QApplication::notify,以在那里处理异常,但是他们没有被捕获。

我的问题是,我是否做错了根本性的事情?此外,作为替代方案,是否可以从我的 C++ 类中显式抛出脚本异常?

提前致谢

编辑:修复了包含 catch(...) 语句的描述。

更新(解决方案): 我通过遵循与接受的答案中概述的策略类似的策略“修复”了这个问题。虽然我还没有找到 linux 上没有捕获异常的原因(我现在怀疑 m_engine->evaluate 在 linux 上产生了一个单独的线程),但我已经开始使用 intended Qt 脚本中的异常抛出方式,即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);
}

现在是这样的:(特别注意返回类型)

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();
}

那么在哪里处理这些脚本错误呢?在调用 QScriptEngine::evaluate() 之后,您可以使用 QScriptEngine::hasUncaughtException() 检查是否有任何未捕获的异常。 , 用 uncaughtException() 获取错误对象,现在你在脚本中有发生错误的消息、跟踪和行号!

希望这对某人有所帮助!

最佳答案

在尝试将 SWIG 与 Python 结合使用来包装 C++ 库时,我遇到了类似的问题。最终发生的事情是我为所有包装类创建了一个 stub ,它捕获了异常并安静地失败了。幸运的是,我拥有仅传递容器类和状态模式对象的包装功能,因此我可以轻松检查是否有问题。我可以给你同样的建议吗?

  1. 用另一个函数包装你想要的函数,相同的接口(interface)除了返回值。
  2. 创建一个对象,其中不仅包含请求的返回类型,还包含错误指示符。
  3. 让脚本确保检查异常。

是的,如果您允许脚本引擎访问异常工厂(一个唯一目的是抛出 C++ 异常的类),它很有可能抛出 C++ 异常。

关于c++ - 处理导出到 QtScript 的函数中抛出的 C++ 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3609940/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com