2010-08-31 5 views
5

पर निर्यात किए गए फ़ंक्शन में फेंकने वाले सी ++ अपवाद को संभालना मैं उपयोगकर्ता के कार्यक्षमता तक पहुंचने के लिए वैकल्पिक तरीके के रूप में अपने एप्लिकेशन में क्यूटी स्क्रिप्ट इंजन का उपयोग कर रहा हूं। इस प्रकार, मैं कुछ सी ++ कक्षाओं को क्यूटी स्क्रिप्टइंजिन में निर्यात करता हूं, जो एप्लिकेशन के इंटरफ़ेस के रूप में कार्य करेगा। समस्या यह है कि, इन सी ++ कक्षाएं अपवाद फेंक सकती हैं।क्यूटीस्क्रिप्ट

मेरे पास स्क्रिप्ट को संसाधित करने के अनुरोधों को सुनकर, "स्क्रिप्टइंटरफेस" वर्ग अपने धागे पर चल रहा है। इसलिए जब मैं किसी उपयोगकर्ता की स्क्रिप्ट का मूल्यांकन करता हूं, तो अपवादों को संभालने के लिए मेरे पास एक कोशिश/पकड़ ब्लॉक होता है, और एप्लिकेशन में कंसोल में त्रुटि प्रिंट करता है।

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

यह विंडोज़ में पूरी तरह से काम करता है ... लेकिन कार्यक्रम Linux- में काम नहीं करता इस संदेश के साथ समाप्त हो जाता है:

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

मैं एक कूबड़ है कि यह था, क्योंकि अपवादों के बुलबुले था इवेंट हैंडलर (चूंकि स्क्रिप्ट इंजन मेरे निर्यातित वर्गों में कार्यों को कॉल करने के लिए सिग्नल का उपयोग करता है), इसलिए मैंने अपवादों को संभालने के लिए QApplication :: अधिसूचित किया, लेकिन उन्हें पकड़ा नहीं गया।

मेरा सवाल है, क्या मैं कुछ मौलिक रूप से गलत कर रहा हूं? साथ ही, एक विकल्प के रूप में, क्या मेरे सी ++ कक्षाओं के भीतर से स्क्रिप्ट अपवादों को स्पष्ट रूप से फेंकना संभव है?

अग्रिम

संपादित करें धन्यवाद: वर्णन पकड़ (...) बयान शामिल करने के लिए तय की।

अद्यतन (समाधान): मैंने स्वीकार किए गए उत्तर में उल्लिखित एक रणनीति के अनुसार इस समस्या को "तय" किया। यद्यपि मैं इस स्रोत पर नहीं गया हूं कि अपवादों को लिनक्स पर क्यों नहीं पकड़ा गया है (अब मेरा संदेह है, यह है कि m_engine-> लिनक्स पर एक अलग थ्रेड का मूल्यांकन करें), लेकिन मैंने इरादा का उपयोग करना शुरू कर दिया है क्यूटी लिपियों में अपवाद फेंकना, और यह 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() के साथ त्रुटि ऑब्जेक्ट प्राप्त करें, और अब आपके पास स्क्रिप्ट में संदेश, ट्रेस और लाइन नंबर है जहां त्रुटि हुई!

उम्मीद है कि यह किसी की मदद करेगा!

+0

वहाँ किसी भी है [अपवाद विनिर्देशों] के साथ कार्य करें (http://www.gotw.ca/publications/mill22.htm) शामिल है? –

+0

मेरी कक्षाओं में कहीं भी नहीं –

+0

क्या पकड़ है (...) {} 'उस अपवाद को पकड़ें? – tibur

उत्तर

3

सी ++ पुस्तकालयों को लपेटने के लिए पायथन के साथ SWIG का उपयोग करने की कोशिश करते समय मैं इसी तरह की समस्या में भाग गया। आखिर में क्या हुआ था कि मैंने सभी लपेटा वर्गों के लिए एक स्टब बनाया जो अपवाद पकड़ा और चुपचाप विफल रहा। सौभाग्य से मेरे पास लपेटने की कार्यक्षमता की लक्जरी थी जो केवल कंटेनर कक्षाओं और राज्य पैटर्न वस्तुओं को पारित करती थी, इसलिए मैं आसानी से जांच सकता था कि कुछ ख़राब था या नहीं। क्या मैं आपके लिए भी यही सुझाव दे सकता हूं?

  1. फ़ंक्शन वैल्यू को छोड़कर एक ही फ़ंक्शन, समान इंटरफ़ेस के साथ इच्छित कार्यों को लपेटें।
  2. ऐसी ऑब्जेक्ट बनाएं जिसमें न केवल अनुरोधित वापसी प्रकार है बल्कि एक त्रुटि संकेतक भी शामिल है।
  3. क्या स्क्रिप्ट अपवादों की जांच करने के लिए सुनिश्चित करें।

और हाँ, यह एक स्क्रिप्ट इंजन सी ++ अपवाद फेंकने के लिए के लिए बहुत संभव है यदि आप इसे एक अपवाद कारखाने पहुंच प्रदान की है (एक वर्ग जिनका एकमात्र उद्देश्य सी ++ अपवाद फेंकने के लिए है।)

+1

सुपर देर से स्वीकार करते हैं, लेकिन मैं इस सप्ताह इस समस्या पर वापस आया और मूल रूप से आपके द्वारा वर्णित कुछ के समान कुछ किया। मैं अपने विशिष्ट मामले के लिए अपना समाधान दिखाने के लिए अपनी पोस्ट संपादित करूंगा। धन्यवाद! –

1

अपने प्रोग्राम को डीबगर के तहत चलाएं और अपने रनटाइम लाइब्रेरी के टर्मिनेट() फ़ंक्शन के अंदर ब्रेकपॉइंट रखें। इस तरह आप डीबगर में समाप्त() को रोक देंगे और कॉल स्टैक का निरीक्षण करके आप देखेंगे कि कहां समाप्त किया गया था() कहलाता था।