2010-08-12 12 views
5

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

बस स्पष्ट करने के लिए: कहें कि मुझे एक संकलित स्थिर लाइब्रेरी मिली है जो क्लास फू को परिभाषित करती है इस:

class Foo 
{ 
public: 
    // Constructor 
    Foo() 
    { 
     /* ... Do stuff ... */   
     if (stuffwentwrong) 
      throw(123); // We throw an integer error code (to make it simple) 
    } 
}; 

और कुछ पुरुष इस तरह इसे इस्तेमाल करता है:

try 
{ 
    Foo foo_object; 
} 
catch (int i) 
{ 
    std::cout << "Oh bum. Code: " << i; 
} 

कि सुरक्षित होगा?

+0

वहाँ समस्याओं (लगभग 15 वर्ष पूर्व) इन सुलझाई जा सकती (जब तक आप गतिशील रूप से लोड हो रहा है/सब अपने आप से DLL उतारने की तरह अजीब बातें कर रहे हैं) थे। यदि आप सीधे डीएलएल का उपयोग कर रहे हैं तो आपको ठीक होना चाहिए। –

उत्तर

3

और विशेष रूप से बुला कोड और पुस्तकालय आम तौर पर विभिन्न compilers

आप के साथ संकलित कर रहे हैं अलग सी ++ compilers कि संगत ABI नहीं है मिश्रण नहीं कर सकते। इसलिए, उदाहरण के लिए, आप एमएसवीसी के साथ संकलित पुस्तकालय से अपवाद नहीं फेंक सकते हैं और जीसीसी के साथ पकड़ने की कोशिश कर सकते हैं।

लेकिन अन्यथा, आपको आमतौर पर कोई समस्या नहीं है।

छोटे ध्यान दें:

MSVC कई असंगत अपवाद मॉडल, उन्हें मिश्रित नहीं होते है।

+0

वहां कई अन्य सूक्ष्मताएं हैं जो सामान्य रूप से खतरनाक बनाती हैं। उदाहरण के लिए यदि डीएलएल को सीआरटी के एक अलग संस्करण के साथ संकलित किया गया है तो आप खराब हो जाएंगे (उदा। डीबग बनाम रिलीज, या मल्टीथ्रेड बनाम सिंगल थ्रेडेड)।इसके अलावा सीआरटी मॉड्यूल स्तर पर कुछ राज्य संग्रहीत करता है, न कि प्रक्रिया स्तर (उदाहरण के लिए एचएमओएल, या मेमोरी ट्रैकिंग जानकारी), इसलिए जब आप डीआरएल सीमाओं में सीआरटी-निर्भर वस्तुओं को प्रेषित करते हैं तो ये सभी चीजें सिंक से बाहर हो सकती हैं। और त्रुटियां रन-टाइम पर हैं, और बहुत सूक्ष्म/सिर-स्क्रैचर्स हो सकती हैं। सामान्य रूप से इससे बचें। – tenfour

0

आपका उदाहरण आपको ठीक काम करना चाहिए, हालांकि डीएलएल के साथ, यदि आप एक ढेर आवंटित अपवाद फेंकने के लिए होते हैं, तो आप दुर्घटनाग्रस्त हो जाएंगे यदि डीएलएल का उपभोक्ता ढेर आवंटित अपवाद को मुक्त करने का प्रयास करता है।

3

जीसीसी के संबंध में, कम से कम एक मामले में जहां जीसीसी से पकड़ने अपवाद साझा जेनरेट पुस्तकालयों समस्याएं खड़ी कर सकता है, यानि कि जब साझा लाइब्रेरी का throw सक्षम प्रकार निर्यात करने के लिए भूल जब प्रतीक दृश्यता "hidden" डिफ़ॉल्ट रूप से है। GCC Visibility Wiki पृष्ठ इस मुद्दे के बारे में अच्छी जानकारी देता है, और इसे कैसे रोकें।

मुझे यकीन नहीं है कि विंडोज डीएलएल के समान समस्याएं हैं, लेकिन ऐसा लगता है।

1

जनरल पकड़ लिया जब यह DLLs और अपवादों की बात आती है:

शीर्षक में अपवाद वर्ग इनलाइन को लागू न करें। आप डुप्लिकेट vtables और RTTI जानकारी के साथ समाप्त हो जाएंगे, जिसके परिणामस्वरूप उपयोग कोड में पकड़े नहीं जा रहे अपवाद (डुप्लिकेशंस के कारण, अपवाद को किसी अन्य प्रकार के रूप में माना जाता है)।

विवरण:

http://marcmutz.wordpress.com/2010/08/04/fun-with-exceptions/

संबंधित मुद्दे