सी . में लिनक्स ड्लोपेन सिस्टम

Si Mem Linaksa Dlopena Sistama



पुस्तकालय समारोह dlopen() सी भाषा में एक बहुत ही उपयोगी कार्य है। फ़ंक्शन लाइब्रेरी को एक नया खोलने के बाद मेमोरी में लोड करता है। हम आम तौर पर इसका उपयोग पुस्तकालय प्रतीकों को लोड करने के लिए करते हैं जो संकलन समय पर अज्ञात होते हैं। Dlopen() एक ऐसा फंक्शन है जो हमारे प्रोग्राम्स में इस्तेमाल होता है। DL पुस्तकालय dlopen () को लागू करता है, जिसे Dlfcn.h में परिभाषित किया गया है। dlopen फ़ंक्शन के लिए दो पैरामीटर आवश्यक हैं: लाइब्रेरी फ़ाइल का नाम और ध्वज। फ़ाइल का नाम एक गतिशील पुस्तकालय है, और यह परिभाषित करता है कि पुस्तकालय की निर्भरता की गणना तुरंत की जाती है या नहीं। dlopen() एक 'हैंडल' लौटाता है जिसे एक अपारदर्शी मान के रूप में माना जाना चाहिए और अन्य DL पुस्तकालय संचालन इसका उपयोग करते हैं। यदि लोड करने का प्रयास असफल होता है, तो dlopen() NULL लौटाता है। लेकिन dlopen() उसी फ़ाइल हैंडल को लौटाता है यदि वह एक ही लाइब्रेरी को कई बार लोड करता है।

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

उदाहरण 1:

अब, सी भाषा में dlopen फ़ंक्शन की कार्यक्षमता देखने के लिए निम्न उदाहरण पर विचार करें। पहले चरण में, हम कुछ सी मानक पुस्तकालयों को लोड करते हैं। यहां, हम नई लाइब्रेरी 'dlfcn.h' लोड करते हैं जिसका उपयोग dlopen मोड तर्क का निर्माण करते समय मैक्रोज़ को परिभाषित करने के लिए किया जाता है।







फिर, हम अपने कार्यक्रम 'gnu/lib-name.h' के अंदर एक और पुस्तकालय पेश करते हैं। GNU libc के साथ शामिल साझा लाइब्रेरी फ़ाइलें उपयोगकर्ता प्रोग्राम द्वारा मैक्रोज़ के अनुसार पाई जाती हैं जिसे वह परिभाषित करता है। जीएनयू सी लाइब्रेरी जीएनयू और जीएनयू/लिनक्स ऑपरेटिंग सिस्टम के साथ-साथ अन्य लिनक्स-आधारित सिस्टम की एक विस्तृत श्रृंखला के लिए मौलिक पुस्तकालय प्रदान करती है। उसके बाद, हमारे पास मुख्य विधि कार्यान्वयन है। उसके अंदर, हम पॉइंटर ऑब्जेक्ट 'हैंडल' को शून्य कीवर्ड के साथ घोषित करते हैं। हम एक पॉइंटर साइन फ़ंक्शन घोषित करते हैं जिसमें डेटा प्रकार डबल होता है। त्रुटि प्रबंधन के लिए सूचक वस्तु 'त्रुटि' की एक और घोषणा है।



उसके बाद, हम 'हैंडल' ऑब्जेक्ट के अंदर dlopen फ़ंक्शन को लागू करते हैं। dlopen दो तर्क लेता है: LIBM_SO और 'RTLD_LAZY'। यहां, 'LIBM_SO' लाइब्रेरी फ़ाइल का नाम है जो त्रिकोणमितीय कार्यों जैसे गणितीय कार्य प्रदान करता है। यह साझा पुस्तकालय आवश्यक है क्योंकि हम साइन फ़ंक्शन का उपयोग करते हैं। 'RTLD_LAZY' एक और तर्क है जो dlopen फ़ंक्शन को कॉल करता है। जब किसी दिए गए प्रतीक को पहली बार संदर्भित किया जाता है, तो कार्यान्वयन द्वारा निर्धारित समय पर स्थानांतरण किया जाना चाहिए।



चूंकि एक प्रक्रिया निष्पादन योग्य ऑब्जेक्ट फ़ाइल में प्रत्येक प्रतीक को संदर्भित नहीं कर सकती है, इसलिए RTLD LAZY को निर्दिष्ट करना कार्यान्वयन पर प्रदर्शन को बढ़ाना चाहिए जो गतिशील प्रतीक बंधन को सक्षम करता है। इसके बाद, जब हैंडल ऑब्जेक्ट dlopen फ़ंक्शन करने में विफल रहता है, तो हमारे पास त्रुटि प्रबंधन के लिए एक और स्थिति होती है। हम त्रुटि को दूर करने के लिए dlerror कहते हैं।





dlerror() फ़ंक्शन एक नल-टर्मिनेटेड स्ट्रिंग प्रदान करता है जो मानव-पठनीय है और हाल की त्रुटि की रिपोर्टिंग को निर्दिष्ट करता है जो पिछले dlerror कॉल के बाद से dlopen API कॉलों में से किसी एक को कॉल के कारण होती है। फिर, हम फ़ंक्शन को इस तरह से कास्ट करते हैं: '(*void**)(&sine)= dlsym(handle, sin)'। जैसा कि यह अजीब है, कास्टिंग आईएसओ सी का अनुपालन करता है जो संकलक से चेतावनियों से बचा जाता है। हम dlsym फ़ंक्शन को नियोजित करते हैं जो एक डायनामिक लिंक मॉड्यूल के अंदर निर्दिष्ट प्रतीक का पथ प्राप्त करता है जो एक dlopen() फ़ंक्शन के माध्यम से सुलभ है।

साथ ही, हम मानक त्रुटि के लिए फिर से if-else ऑपरेशन करते हैं जो तब उत्पन्न होता है जब dlerror() NULL नहीं होता है। फिर, हमारे पास एक प्रिंटफ स्टेटमेंट है जहां हम गणना करने के लिए साइन वैल्यू निर्दिष्ट करते हैं। अंतिम चरण में, हम dlopen () द्वारा लौटाए गए हैंडल के लिए dlclose को कॉल करके उस साझा ऑब्जेक्ट को बंद कर देते हैं।



#शामिल करें
#शामिल करें
#शामिल करें
#शामिल करें

पूर्णांक
मुख्य ( पूर्णांक एर्गसी , चारो ** अर्जीवी )
{
शून्य * सँभालना ;
दोहरा ( * उन लोगों के ) ( दोहरा ) ;
चारो * गलती ;

सँभालना = डलोपेन ( LIBM_SO , RTLD_LAZY ) ;
यदि ( ! सँभालना ) {
एफप्रिंटफ ( स्टेडर , '%एस \एन ' , dlerror ( ) ) ;
बाहर निकलना ( EXIT_FAILURE ) ;
}
dlerror ( ) ;

* ( शून्य ** ) ( और उन लोगों के ) = डीएलएसआईएम ( सँभालना , 'बिना' ) ;

यदि ( ( गलती = dlerror ( ) ) != शून्य ) {
एफप्रिंटफ ( स्टेडर , '%एस \एन ' , गलती ) ;
बाहर निकलना ( EXIT_FAILURE ) ;
}

printf ( '%एफ \एन ' , ( * उन लोगों के ) ( 4.0 ) ) ;
डीएलक्लोज़ ( सँभालना ) ;
बाहर निकलना ( EXIT_SUCCESS ) ;
}

हम C संकलन कमांड के साथ -ldl विकल्प का उपयोग करते हैं क्योंकि यह dlopen लिंक्ड इंटरफ़ेस के लिए लाइब्रेरी है और इसकी आवश्यकता है। जब dlopen फ़ाइल का निष्पादन किया जाता है, तो यह पहले दिए गए मान का साइन मान प्रदर्शित करता है।

उदाहरण 2:

अब, हम dlopen फ़ंक्शन का उपयोग करने का एक और उदाहरण लेते हैं। हम अपने प्रोग्राम को dlopen कोड के कार्यान्वयन के लिए सभी आवश्यक C लाइब्रेरी के साथ लोड करते हैं। फिर, हम अपना प्रोग्राम main मेथड के अंदर शुरू करते हैं। यहां, हम चर 'src' की घोषणा के साथ स्ट्रिंग को परिभाषित करते हैं। फिर हम पॉइंटर वैरिएबल 'स्ट्रेल', 'हैंडल' और 'एरर' घोषित करते हैं।

इसके बाद, हम हैंडल वेरिएबल को कॉल करते हैं और dlopen फ़ंक्शन को परिनियोजित करते हैं। dlopen फ़ंक्शन स्ट्रिंग हैंडलिंग फ़ंक्शंस और ध्वज 'RTLD_LAZY' के लिए साझा लाइब्रेरी 'libstr.so' इनपुट करता है जो पहले से ही पिछले उदाहरण में प्रदर्शित किया गया है। हम 'त्रुटि' चर के अंदर dlerror फ़ंक्शन को dlopen फ़ंक्शन द्वारा उत्पन्न त्रुटि को साफ़ करने के लिए आमंत्रित करते हैं। if-else का उपयोग त्रुटियों की जांच के लिए किया जाता है।

फिर, हम dlsym फ़ंक्शन का उपयोग करके strlen फ़ंक्शन का पता प्राप्त करते हैं और ऐसा करते समय त्रुटियों को सत्यापित करते हैं। इसके बाद, हम दिए गए स्ट्रिंग की लंबाई वापस करने के लिए strnlen फ़ंक्शन को कॉल करने के लिए printf फ़ंक्शन का उपयोग करते हैं। अंत में, हम साझा लाइब्रेरी को dlclose फ़ंक्शन के साथ बंद करते हैं।

#शामिल करें
#शामिल करें
#शामिल करें
#शामिल करें
पूर्णांक मुख्य ( शून्य )
{
चारो * एसआरसी = 'हैलो लिनक्स' ;
पूर्णांक ( * स्ट्रेलेन ) ( स्थिरांक चारो * ) ;
शून्य * सँभालना ;
चारो * गलती ;


सँभालना = डलोपेन ( './libstr.so' , RTLD_LAZY ) ;
गलती = dlerror ( ) ;
यदि ( ! सँभालना || गलती != शून्य ) { printf ( 'लाइब्रेरी लोड हो रहा है प्रयास विफल! \एन %एस \एन ' , गलती ) ;
वापसी - 1 ; }

स्ट्रेलेन = डीएलएसआईएम ( सँभालना , 'स्ट्रेलेन' ) ;
गलती = dlerror ( ) ;
यदि ( ! स्ट्रेलेन || गलती == शून्य ) { printf ( '%एस \एन ' , गलती ) ; वापसी - 1 ; }

printf ( 'स्ट्रिंग की लंबाई है:%d \एन ' , स्ट्रेलेन ( एसआरसी ) ) ;
डीएलक्लोज़ ( सँभालना ) ;
वापसी 0 ;
}

हम दिए गए प्रोग्राम के निष्पादन के लिए निम्न कमांड का उपयोग करते हैं। यहां, स्ट्रिंग लंबाई फ़ंक्शन के लिए -lstr ध्वज का उपयोग किया जाता है और ldl का उपयोग dlopen लाइब्रेरी फ़ाइल के लिए किया जाता है। संकलित प्रोग्राम शेल में दिखाए गए अनुसार स्ट्रिंग की लंबाई देता है:

निष्कर्ष

इस लेख में C भाषा के dlopen function के बारे में जानकारी प्रदान की गई है। हमारे पास dlopen फ़ंक्शन का संक्षिप्त परिचय है। फिर, हमने दो उदाहरण लागू किए। फ़ंक्शन एक पहचानकर्ता देता है जो खुले पुस्तकालय को परिभाषित करता है। खुले पुस्तकालय के अंदर कार्यों के पते तब इस पहचानकर्ता और dlsym फ़ंक्शन का उपयोग करके निर्धारित किए जाते हैं। लाइब्रेरी के भीतर एक फ़ंक्शन का पता जो पहले से ही dlopen का उपयोग करके खोला गया है, उसे dlsym फ़ंक्शन का उपयोग करके पाया जा सकता है।