ユーザーがその機能にアクセスするための代替手段として、アプリケーションで Qt スクリプト エンジンを使用しています。そのため、いくつかの C++ クラスを Qt ScriptEngine にエクスポートします。これは、アプリケーションへのインターフェイスとして機能します。問題は、これらの C++ クラスが例外をスローする可能性があることです。
独自のスレッドで実行されている「ScriptInterface」クラスがあり、スクリプトを処理するためのリクエストをリッスンしています。そのため、ユーザーのスクリプトを評価するときは、例外を処理するために try/catch ブロックを前後に配置し、アプリケーションのコンソールにエラーを出力します。
...
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で例外がキャッチされない理由のソースには行っていませんが(現在、私の疑いは、Linuxでm_engine->evaluateが別のスレッドを生成することです)、意図した例外スローの方法を使い始めました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()
、エラーが発生したスクリプトのメッセージ、トレース、および行番号が表示されます。
これが誰かを助けることを願っています!