2013-05-13 4 views
8

मेरा मामला बहुत आसान है: मैं अपने सी ++ प्रोग्राम यूनिक्स सिग्नल से निपटने के लिए चाहता हूं। ऐसा करने के लिए, glibc सिग्नल.h में एक फ़ंक्शन प्रदान करता है जिसे sigaction कहा जाता है, जो फ़ंक्शन पॉइंटर को इसके दूसरे तर्क के रूप में प्राप्त करने की अपेक्षा करता है।सी लाइब्रेरी के लिए सी लिंकेज सी पुस्तकालय

extern "C" 
{ 
void uponSignal(int); 
} 

void uponSignal(int) 
{ 
    // set some flag to quit the program 
} 

static 
void installSignalHandler() 
{ 
    // initialize the signal handler 
    static struct sigaction sighandler; 
    memset(&sighandler, 0, sizeof(struct sigaction)); 
    sighandler.sa_handler = uponSignal; 

    // install it 
    sigaction(SIGINT, &sighandler, nullptr); 
} 

मेरा प्रश्न है: extern "C" लिंकेज विनिर्देशक आवश्यक है?

बोनस प्रश्न: क्या सिग्नल static घोषित किया जा सकता है?

+0

कुछ कंपाइलर्स इसे संकलित करने से इंकार कर देंगे यदि आप 'बाहरी "सी' 'को हटाते हैं क्योंकि सिग्नेशन के दूसरे तर्क में गलत प्रकार है। यह कई कंपाइलर्स में एक बग है कि वे फ़ंक्शन प्रकार के लिंकेज हिस्से पर विचार नहीं करते हैं। –

उत्तर

4

extern C केवल तभी जरूरी है जब आप अपने बाइनरी से अपने प्रतीक निर्यात करते हैं या नाम मैंगलिंग से बचने के लिए उन्हें अन्य बाइनरी (आमतौर पर दोनों मामलों में, एक साझा लाइब्रेरी) से आयात करते हैं।

यहां यह मामला नहीं है, आप विभिन्न बाइनरी में uponSignal को लिंक नहीं कर रहे हैं, इसलिए आपको extern C की आवश्यकता नहीं है। आप जो भी कर रहे हैं वह आपके फ़ंक्शन का पता sigaction पर एक फ़ंक्शन से पास कर रहा है जो पहले से ही uponSignal का पता जानता है क्योंकि वे एक ही अनुवाद इकाई के (स्पष्ट रूप से) भाग हैं, या कम से कम बाइनरी में हैं।

बोनस प्रश्न: uponSignal को static घोषित किया जा सकता है?

निश्चित रूप से यदि आप चाहते हैं। uponSignal को वैसे भी बाहरी लिंकेज की आवश्यकता नहीं है।

+1

असल में, मैं नाम उलझन से ** कॉलिंग कन्वेंशन ** के बारे में अधिक चिंतित था। – qdii

+2

आपको नहीं करना चाहिए। ;) भले ही सम्मेलन कॉलिंग कार्यान्वयन-विशिष्ट (यानी मानक के दायरे से बाहर) हैं, मैंने कभी ऐसा संकलक नहीं देखा है जिसने फ़ंक्शन हस्ताक्षर के कॉलिंग सम्मेलन का हिस्सा नहीं बनाया है ताकि संकलक आपको चेतावनी देगा कि वहां कभी एक मेल नहीं है (जो शायद ही कभी होता है)। – syam

6

मेरा प्रश्न है: extern "C" लिंकेज विनिर्देशक आवश्यक है?

अधिकतम पोर्टेबिलिटी के लिए, हाँ; सी ++ मानक केवल extern "C" घोषित कार्यों के माध्यम से सी के साथ इंटरऑपरेबिलिटी की गारंटी देता है।

व्यावहारिक रूप से, नहीं; सबसे समझदार एबीआई (ग्लिब द्वारा उपयोग किए गए जीएनयू एबीआई समेत) सी और सी ++ गैर-सदस्य (और स्थैतिक सदस्य) कार्यों के लिए एक ही कॉलिंग सम्मेलन का उपयोग करेंगे, ताकि extern "C" केवल भाषाओं के बीच फ़ंक्शन नाम साझा करने की आवश्यकता हो।

बोनस प्रश्न: uponSignal स्थिर घोषित किया जा सकता है?

हां। बाहरी संपर्क केवल अन्य अनुवाद इकाइयों के नाम से फ़ंक्शन तक पहुंचने के लिए आवश्यक है; फ़ंक्शन पॉइंटर के माध्यम से फ़ंक्शन को कॉल करना आवश्यक नहीं है।

+0

क्या आपके पास वापस जाने का उद्धरण होगा "सी ++ मानक केवल सी" के साथ घोषित समारोह के माध्यम से सी के साथ अंतःक्रियाशीलता की गारंटी देता है "? – qdii

+1

@qdii: वास्तव में नहीं; ऐसा कुछ भी नहीं है जो स्पष्ट रूप से कहता है कि कोई गारंटी नहीं है, केवल कुछ भी नहीं जो गारंटी प्रदान करता है। 7।5/1 निर्दिष्ट करता है कि "अलग-अलग भाषा संबंधों के साथ दो फ़ंक्शन प्रकार अलग-अलग प्रकार होते हैं, भले ही वे अन्यथा समान हों", और एक नोट यह इंगित करता है कि "एक विशेष भाषा संबंध [...] एक विशेष कॉलिंग सम्मेलन आदि से जुड़ा हो सकता है। । " –

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