यह कैसे स्पष्ट करें कि एक फ़ंक्शन को बाहर से एक्सेस किया जा रहा है?


9

यह एक C विशिष्ट प्रश्न है। मैं .hफ़ाइल के माध्यम से केवल कुछ कार्यों को उजागर करते हुए, अनुवाद इकाई की सीमाओं के अंदर सब कुछ संभव रखने की कोशिश कर रहा हूं । यही है, मैं staticफ़ाइल-स्तरीय ऑब्जेक्ट के लिए लिंकेज दे रहा हूं ।

अब, कुछ कार्यों को अन्य मॉड्यूल द्वारा बुलाया जाना चाहिए, लेकिन सीधे नहीं। मेरा मॉड्यूल / फ़ाइल / अनुवाद इकाई दूसरे मॉड्यूल को सब्सक्राइब करता है, जो किसी फ़ंक्शन को पॉइंटर पास करता है। फिर, एक विशेष घटना पर, सूचक को कुछ तर्कों के साथ बुलाया जाता है।

इसलिए मैं सोच रहा हूं कि यह कैसे स्पष्ट किया जाए कि उन कार्यों को कुछ अस्पष्ट स्थान से कहा जाता है।

  • क्या उन्हें ( staticया externउन्हें उजागर करना चाहिए .h)?
  • क्या मुझे कार्यों के नाम में कुछ संकेत शामिल करना चाहिए?
  • या क्या "एक्स द्वारा बुलाया" टिप्पणी डालना पर्याप्त है?

1
यह एक उत्कृष्ट प्रश्न है। मेरा समाधान (जिसके साथ मैं बहुत खुश नहीं हूं, इसीलिए मैं इसे केवल एक टिप्पणी में डाल रहा हूं) कई हेडर फाइलें, समझदारी से नाम, और कार्यक्षेत्रों को समूहीकरण करने के लिए है जो मैं चाहता हूं कि वे करें। मेरे द्वारा बनाई गई AStar लाइब्रेरी के लिए, मैंने AStar.h, AStar_pStreet.h, AStar_packagePStreet.h, आदि ...
शिवन ड्रैगन

जवाबों:


2

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

चूंकि सीआई के प्रत्येक कार्यान्वयन में लिंकेज प्रतीकात्मक है, जो कुछ भी फ़ंक्शन को कॉल करता है उसे अपने प्रतीक का उल्लेख करना चाहिए:

foo();  /* Direct */

some_function_pointer_t funcs[] = { &foo, &bar, &baz };  /* Indirect */

यदि आप गलती foo()से होने की घोषणा करते हैं static, तो आपका प्रोग्राम लिंक नहीं करेगा। यदि आप इसे गैर घोषित करते हैं static, तो आपके पास एक उजागर कार्य है जिसे कहा नहीं जाता है। किसी फ़ंक्शन का उपयोग किया जाता है या नहीं, इसके बारे में प्रश्न आपके ऑब्जेक्ट फ़ाइलों के प्रतीक तालिकाओं को डंप करके या स्रोतों में खोजकर हल किया जा सकता है।


1

इसलिए मैं भटक रहा हूं कि यह कैसे स्पष्ट किया जाए कि उन कार्यों को कुछ अस्पष्ट स्थान से कहा जाता है।

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

क्या उन्हें स्थिर या बाहरी होना चाहिए (और उन्हें .h में उजागर करना)?

static यह तब तक ठीक हो सकता है जब तक आपके पास कोई वर्ग [जैसे निर्माण] न हों जिसमें उदाहरण डेटा हो।
externइसका मतलब है कि आप वास्तव में इसे लागू नहीं करते हैं; लिंकिंग प्रक्रिया के दौरान कहीं और से "अधिग्रहण" किया जाता है।

क्या मुझे कार्यों के नाम में कुछ संकेत शामिल करना चाहिए?

या क्या "एक्स द्वारा बुलाया" टिप्पणी डालना पर्याप्त है?

बिलकुल नहीं।

इस तरह की टिप्पणियाँ, चाहे कितनी भी अच्छी तरह से क्यों न हों, अप्रचलित हैं जिस क्षण आप उन्हें लिखना समाप्त कर देते हैं।


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

1
दूसरे बिंदु के बारे में, जहाँ तक मेरी समझ जाती है, फ़ाइल स्कोप पर परिभाषित ऑब्जेक्ट, डिफ़ॉल्ट रूप से बाहरी लिंकेज है; इसलिए externकीवर्ड निरर्थक है
वोरैक

0

यदि कॉलबैक फ़ंक्शन आपके मॉड्यूल के भीतर परिभाषित किए गए हैं और उपयोगकर्ता कभी भी अपना स्वयं का एक प्रदान नहीं करेगा, तो मुझे लगता है कि आप आरंभीकरण चरण के दौरान एक प्लेसहोल्डर का उपयोग कर सकते हैं। प्लेसहोल्डर आमतौर पर एक है enumजो तब आंतरिक रूप से सही staticफ़ंक्शन में अनुवादित होता है।


0

मैं उन्हें अभी भी बनाऊंगा static(वे केवल किसी के द्वारा लिंक किए गए और कॉल किए जाने के लिए अभिप्रेत नहीं हैं), और उनके उद्देश्य को चिह्नित करते हैं क्योंकि उनके नाम पर बाहरी कार्यों को आपूर्ति की जाती है।

static क्योंकि मैं छिपाने की कोशिश करता हूं कि मैं क्या छिपा सकता हूं, जितना मैं इसे छिपा सकता हूं।

उन्हें अपने नाम में चिह्नित करें, क्योंकि ए), टिप्पणियां पुरानी हो जाती हैं, और बी), यह उस जगह पर स्पष्ट हो जाता है जहां कॉलबैक की आपूर्ति की जाती है कि इस फ़ंक्शन का उपयोग उस तरह से करने का इरादा है: यह मूल रूप से इसे एक लाल झंडा बनाता है एक फ़ंक्शन का पता लेना जो नामकरण सम्मेलन का पालन नहीं करता है।


0

स्कोप संशोधक को मुख्य रूप से संकलक के लिए जानकारी के रूप में उपयोग किया जाना चाहिए, न कि "करीब पर्याप्त" प्रलेखन के रूप में। staticविशेष रूप से उपयोग करने से C कंपाइलर को मॉड्यूल के बाहर से कार्य करने योग्य बनाने की अनुमति मिलती है, जिसमें कॉलबैक भी शामिल है - न कि आप जो चाहते हैं, भले ही वह आपके वर्तमान कंपाइलर के साथ काम करे।

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

इसलिए, एकमात्र विकल्प बचा है, यह इंगित करने के लिए फ़ंक्शन का नाम है कि यह कॉलबैक है। अधिकांश उदाहरण मैंने उपयोग _callbackया _cbप्रत्यय के रूप में, या cb_उपसर्ग के रूप में देखे हैं । लंबे फॉर्म का उपयोग करें यदि कॉलबैक आपके कोड में असामान्य है, तो संक्षिप्त रूप यदि वे सामान्य हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.