Tôi đang sử dụng công cụ tập lệnh Qt trong ứng dụng của mình như một cách thay thế để người dùng truy cập chức năng của nó. Như vậy, tôi xuất một số lớp C++ sang Qt ScriptEngine, nó sẽ là giao diện cho ứng dụng. Vấn đề là, các lớp C++ có thể ném ngoại lệ.Xử lý ngoại lệ C++ được ném vào hàm được xuất sang QtScript
Tôi có một lớp "ScriptInterface" chạy trên chuỗi riêng của mình, lắng nghe các yêu cầu xử lý tập lệnh. Vì vậy, khi tôi đánh giá kịch bản của người dùng, tôi có một khối try/catch xung quanh nó để xử lý các trường hợp ngoại lệ, và in lỗi tới bàn điều khiển trong ứng dụng.
...
try {
m_engine->evaluate(script, name);
}
catch (Exception const& e) {
// deal with it
}
catch (...) {
// scary message
}
này hoạt động hoàn hảo trong các cửa sổ ... nhưng không hoạt động trong linux- chương trình kết thúc với thông điệp này:
terminate called after throwing an instance of 'Basilisk::InvalidArgumentException'
what(): N8Basilisk24InvalidArgumentExceptionE
Aborted
Tôi đã có một linh cảm rằng đó là vì các trường hợp ngoại lệ sôi nổi xử lý sự kiện (vì công cụ script sử dụng các tín hiệu để gọi các hàm trong các lớp đã xuất của tôi), vì vậy tôi đã thực hiện lại QApplication :: thông báo, để xử lý các ngoại lệ ở đó, nhưng chúng không bị bắt.
Câu hỏi của tôi là, tôi đang làm điều gì đó sai về cơ bản? Ngoài ra, như là một thay thế, là nó có thể rõ ràng ném ngoại lệ kịch bản từ bên trong lớp C++ của tôi?
Cảm ơn trước
EDIT: sửa mô tả để bao gồm câu lệnh bắt (...).
CẬP NHẬT (GIẢI PHÁP): Tôi "cố định" vấn đề này bằng cách làm theo một chiến lược tương tự như chiến lược được nêu trong câu trả lời được chấp nhận. Mặc dù tôi đã không đi đến nguồn gốc của lý do tại sao các trường hợp ngoại lệ không bị bắt trên Linux (nghi ngờ của tôi bây giờ, là m_engine-> đánh giá đẻ trứng một thread riêng biệt trên linux), nhưng tôi đã bắt đầu sử dụng dự định cách ngoại lệ ném trong Tập lệnh Qt, và đó là QScriptContext::throwError()
.
Trong trường hợp chức năng của tôi sẽ trông như thế này: (ví dụ ngẫu nhiên)
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);
}
Nó bây giờ là thế này: (đặc biệt chú ý đến kiểu trả về)
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();
}
Vì vậy, nơi nào một đối phó với các lỗi tập lệnh này? Sau khi gọi tới QScriptEngine::evaluate()
, bạn có thể kiểm tra xem có bất kỳ ngoại lệ không bị bắt buộc nào, với QScriptEngine::hasUncaughtException()
, lấy đối tượng lỗi với uncaughtException()
và bây giờ bạn có thông báo, dấu vết và số dòng trong tập lệnh có lỗi xảy ra!
Hy vọng điều này sẽ giúp ai đó ra ngoài!
Có chức năng với [đặc tả ngoại lệ] (http://www.gotw.ca/publications/mill22.htm) có liên quan? –
Không phải bất kỳ nơi nào trong lớp học của tôi –
Có 'catch (...) {}' bắt ngoại lệ đó không? – tibur