2011-08-31 8 views
5

मैं सी ++ में लागू लाइब्रेरी से लिंक करने वाले सी प्रोग्राम में setjmp और longjmp का उपयोग करना चाहता हूं (लेकिन एक सी एपीआई है)।सी ++ पुस्तकालयों से लिंक करते समय सी में setjmp और longjmp का उपयोग

सी ++ कोड गतिशील स्मृति आवंटन करता है और पॉइंटर्स एपीआई के माध्यम से पारित हो जाते हैं, लेकिन जब तक कोड की सी पक्ष सही ढंग से उन (अपारदर्शी) वस्तुओं को प्रबंधित करती है, तो longjmp का उपयोग करते समय कोई गड़बड़ नहीं होनी चाहिए, सही?

मुझे पता है कि इन कार्यों को सी ++ कोड में उपयोग करना सुरक्षित नहीं है, लेकिन क्या यह सी कोड में सुरक्षित होना चाहिए जो सी ++ कोड से जुड़ा हुआ है?

उत्तर

3

तथ्य यह है कि आप अपने सी कोड से सी ++ फ़ंक्शंस को कॉल करते हैं, यह सेटजेम्प और लांगजंप को हमेशा से अधिक असुरक्षित नहीं बनाता है।

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

+0

ठीक है। मेरी सोच यह है कि जब तक सी ++ लाइब्रेरी में किए गए आवंटन के पास उचित सी-इंटरफ़ेस कॉल के माध्यम से साफ़ करने का एक तरीका होता है, तो C++ कोड longjmp के प्रभाव से अलग होता है, और अपवाद हैंडलिंग और longjmp प्रत्येक के साथ हस्तक्षेप नहीं कर सकता अन्य। (मैं सी ++ लाइब्रेरी का कार्यान्वयन भी कर रहा हूं।) –

+0

यदि आपके पास सी ++ लाइब्रेरी में अपवाद हैंडलिंग है तो आपको यह सुनिश्चित करना चाहिए कि पुस्तकालय के अंदर किसी भी फेंकने वाले अपवाद पकड़े गए हैं, आप अपवादों को अपने सी ++ कोड से बाहर नहीं करना चाहते हैं (सुनिश्चित नहीं है कि क्या होगा यदि आप ऐसा करते हैं, तो कभी कोशिश नहीं की)। और सी ++ आवंटन जारी करने के लिए, आपको यह पता लगाना होगा कि सी कोड से रिलीज करने की क्या ज़रूरत है जो लांगजंप कॉल के बाद नियंत्रण लेती है। चूंकि आपके पास ऐप और लाइब्रेरी है, इसलिए मुझे यह काम करने के लिए कोई समस्या नहीं दिख रही है। – Miguel

2

setjmp/longjmp सामान्य रूप से सी ++ के साथ उपयोग के लिए सुरक्षित नहीं हैं। वे प्रभावी रूप से अपवादों के व्यवहार को दोहराते हैं, लेकिन स्टैक को सही तरीके से अनदेखा किए बिना (उदाहरण के लिए, वे स्टैक फ्रेम पर ऑब्जेक्ट्स के लिए विनाशकों को नहीं चलाएंगे जिन्हें वे जबरन बाहर निकलते हैं)। जहां संभव हो, अगर आप उन्हें मिला तो अपवादों का उपयोग करें।

+0

ओपी सी ++ में 'setjmp'/'longjmp' का उपयोग करने की कोशिश नहीं कर रहा है, बल्कि एक सी प्रोग्राम जो सी सी इंटरफ़ेस के माध्यम से कुछ सी ++ कोड का उपयोग करता है (जो संभावित रूप से सी के रूप में कॉल करने योग्य कोड में सभी सी ++ - आईएसएम को मास्क करता है, और ऐसा करता है सुरक्षित रूप से)। –

+2

फिर भी, यह निर्भर करता है। यह शायद आपके कोड के भीतर कूदने के लिए सुरक्षित होगा, लेकिन कॉलबैक से बाहर निकलने के लिए 'longjmp' का उपयोग करके) (उदाहरण के लिए) हो सकता है। – duskwuff

+0

कॉलबैक से बाहर निकलने के लिए 'longjmp' का उपयोग करना (जब तक स्पष्ट रूप से ऐसा करने की अनुमति नहीं दी जाती) भाषा के बावजूद खराब विचार की तरह लगता है। आपको सी में भी अपने आप को साफ करना होगा। –

1

अच्छा, सही और सही नहीं। longjmp सामान्य रूप में विनाशकर्ता फोन करेगा नहीं है, तो निम्नलिखित की तरह एक कोड में इसका उपयोग करने: की बुरी बातें होती हैं

void f(jmp_buf jb) 
{ 
    some_cpp_object_with_a_nontrivial_destructor x; 
    if (some_condition) longjmp(jb, 2); 
    // some other code 
} 

सभी प्रकार कर देगा। यदि आप ऐसी स्थितियों से बचते हैं, तो आपको ठीक होना चाहिए। (सामान्य रूप से, longjmp पर किसी भी गैर-तुच्छ विध्वंस वाले ऑब्जेक्ट्स के साथ सक्रिय स्टैक फ्रेम पर कूदना नहीं चाहिए।)

+0

मेरा कोड सी है, इसलिए मैं स्थानीय चर को एक प्रकार के साथ परिभाषित नहीं कर सकता जिसमें एक निर्माता है। इसलिए आपका उदाहरण मेरे प्रश्न पर लागू नहीं है। –

+0

यदि आप सी ++ फ़ंक्शन पर कॉलबैक देते हैं, तो आप एक बहुत ही समान परिदृश्य में समाप्त होते हैं, और कॉलबैक longjmp को कॉल करता है। – zvrba

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