
DynLib पुस्तकालय अपनी परियोजनाओं में अंतर-मॉड्यूल संचार (EXE <-> DLL, DLL <-> DLL) का उपयोग कर डेवलपर्स के लिए सुविधाजनक उपकरण प्रदान करता है और कोड के समय और मात्रा को काफी कम कर देता है।
डायनलिब एक अभिन्न विकास उपकरण बन गया है। बिल्ली के नीचे हम परिणाम साझा करते हैं।
एक पारंपरिक DLL कार्यान्वयन दृष्टिकोण का नुकसान
पारंपरिक दृष्टिकोण (कार्यान्वयन) के मुख्य नुकसान में शामिल हैं:
- नेमस्पेस का उपयोग करने की क्षमता की कमी
- उपयोगिता कोड की एक बड़ी संख्या की आवश्यकता:
- पुस्तकालयों के गतिशील लोडिंग को लागू करते समय;
- वर्गों के माध्यम से इंटरमॉड्यूलर इंटरैक्शन को लागू करते समय, डिस्क्रिप्टर (या अन्य निहित संरचनाओं) और आवरण वर्गों के उपयोग के माध्यम से;
- जब निर्यात किए गए फ़ंक्शंस अपवाद छोड़ सकते हैं, तो मामले में त्रुटि वापसी तंत्र को लागू करना।
DynLib लाइब्रेरी का उपयोग करके इन समस्याओं को हल किया जाता है!
DynLib उदाहरण
1. एक नियमित DLL का उपयोग करना
टास्क। डायनेमिक रूप से कनेक्ट और test_lib.dll लाइब्रेरी का उपयोग करें जो हेडर फ़ाइल में प्रस्तुत इंटरफ़ेस के साथ सरल गणितीय कार्यों को लागू करता है:
निर्णय। आपको निम्नलिखित हेडर फ़ाइल को लिखना होगा और इसे परियोजना से जोड़ना होगा।
प्रीप्रोसेसर एक
परीक्षण :: श्रमजीवी वर्ग उत्पन्न करेगा जो गतिशील रूप से DLL को लोड करता है और इसमें
सम ,
mul और
एप्सिलॉन फ़ंक्शन सूचीबद्ध होते हैं। DLL को एप्लिकेशन से कनेक्ट करने के लिए, आपको दिए गए हेडर फ़ाइल test_lib.hpp को स्रोत कोड में शामिल करना होगा। अगला, वर्ग
परीक्षण की एक वस्तु बनाएँ
:: lib । 'के माध्यम से निर्यात DLL कार्यों तक पहुँच संभव है।' या '->'।
2. Calculator.dll लाइब्रेरी बनाना
टास्क। एक लाइब्रेरी कैलकुलेटर लिखें ।ll, जो योग, दो नंबरों के उत्पाद और वर्गमूल मूल्य की गणना करना चाहिए। लायब्रेरी को गतिशील रूप से लोड करें और प्रत्येक फ़ंक्शन को कॉल करें।
निर्णय
DLL का उपयोग करना
3. Calculator.dll लाइब्रेरी को अपग्रेड करना। अपवादों का उपयोग।
टास्क। कैलकुलेटर में सभी वर्गाकार रूट
sqrt फ़ंक्शन लाइब्रेरी में इनपुट मान गलत होने पर एक त्रुटि लौटाता है।
निर्णय
DLL का उपयोग करना
sqrt1 = 5 what: exception 'class std::invalid_argument' in method 'sqrt' of class '::team::calculator' with message ' 0'
4. आकृतियों का कार्यान्वयन। पुस्तकालय। इंटरफेस का उपयोग।
टास्क। ज्यामितीय आकृतियों (वर्ग, आयत, वृत्त) के साथ काम करने के लिए एक shape.dll लाइब्रेरी बनाएं। सभी आंकड़ों को एक सामान्य इंटरफ़ेस का समर्थन करना चाहिए जिसके माध्यम से आप आंकड़े के केंद्र के निर्देशांक पा सकते हैं।
निर्णय
पुस्तकालय को कैसे जोड़ा जाए
पुस्तकालय हेडर फ़ाइलों के रूप में आता है। कोई .lib और .dll की आवश्यकता नहीं है कनेक्ट करने के लिए, निम्नलिखित निर्देश जोड़ें:
#include <dl/include.hpp>
लाइब्रेरी आइटम
DynLib लाइब्रेरी के कई वर्ग और मैक्रोज़ स्वतंत्र रूप से और एक-दूसरे से अलग-अलग उपयोग किए जा सकते हैं।
DL_BLOCK
अन्य सभी मैक्रो के लिए एक कंटेनर के रूप में कार्य करता है।
DL_BLOCK (
DL_NS_BLOCK
अन्य सभी मैक्रो के लिए एक कंटेनर के रूप में कार्य करता है। एक वर्ग के लिए नामस्थान बनाता है।
DL_NS_BLOCK( (ns0, ns1, ns2 … ) (
DL_EXPORT
को छोड़कर नीचे वर्णित मैक्रोज़ को
DL_BLOCK या
DL_NS_BLOCK में रखा
जाना चाहिएDL_C_LIBRARY
मैक्रो का उद्देश्य उपयोगकर्ता को एक तैयार वर्ग के साथ प्रदान करना है जो DLL के गतिशील लोडिंग और कार्यों के स्वचालित आयात को लागू करता है। एक मैक्रो के रूप में प्रतिनिधित्व किया है:
DL_C_LIBRARY(lib_class) ( ( ret_type, call, (name, import_name), arguments ) )
- lib_class - उस वर्ग का नाम जिसका कार्यान्वयन DynLib लाइब्रेरी उत्पन्न करता है;
- फ़ंक्शंस - DLL द्वारा निर्यात किए गए फ़ंक्शंस को सूचीबद्ध करना। निम्नलिखित प्रारूप की सूची के माध्यम से सेट करें
(ret_type, call, (name, import_name), तर्क)- ret_type - फ़ंक्शन द्वारा लौटाए गए मान का प्रकार;
- कॉल - कॉल प्रारूप, उदाहरण के लिए: __sdtcall, __cdecl, आदि;
- नाम - फ़ंक्शन नाम (उपयोगकर्ता के लिए);
- import_name डीएलएल निर्यात तालिका में निर्दिष्ट फ़ंक्शन का नाम है, जिसमें सजावट (यदि कोई हो) भी शामिल है। यदि नाम और import_name मेल खाते हैं, तो import_name को छोड़ा जा सकता है।
- तर्क - एक सूची (तर्क प्रकार, तर्क नाम, = डिफ़ॉल्ट मान) इनपुट तर्कों को निर्दिष्ट करता है। तर्क नाम और डिफ़ॉल्ट मान छोड़ा जा सकता है ।;
एक उदाहरण:
DL_BLOCK ( DL_C_LIBRARY( my_lib ) ( ( void, __stdcall, (func), (int)(int,s)(double,V,=1.0) ) ( int, __stdcall, (fn, "fn@0"), (int,a) ) ( int, __stdcall, (fn), () ) ) )
DL_C_LIBRARY मैक्रो द्वारा उत्पन्न कक्षाएं DLL सीमाओं के पार नहीं जा सकतींDL_RECORD
DL_RECORD मैक्रो
इंटरमॉड्यूल संचार में उपयोग के लिए एक पैक डेटा संरचना उत्पन्न करता है। इसके अतिरिक्त, एक निर्माता मैक्रो में सूचीबद्ध सभी तर्कों के साथ बनाया जाता है।
DL_RECORD( record_name ) ( (type, name, =default_value) )
एक उदाहरण:
DL_LIBRARY
DL_LIBRARY मैक्रो कई कार्य करता है:
- EXE (DLL) और DLL के बीच इंटरफेस के विवरण (प्रलेखन) के रूप में कार्य करता है;
- डेवलपर को पुस्तकालय कार्यों को स्वचालित रूप से निर्यात करने के लिए आवश्यक संरचनाएं शामिल हैं;
- एक वर्ग को लागू करता है जो किसी दिए गए इंटरफ़ेस के साथ DLL को लोड करता है और उपयोगकर्ता द्वारा निर्यात किए गए कार्यों तक पहुंच प्रदान करता है;
- C ++ अपवादों का सही उपयोग प्रदान करता है:
- डीएलएल के पक्ष में सी ++ अपवादों का स्वत: पकड़;
- डीएलएल की सीमाओं के माध्यम से मूल्य की वापसी, एक अपवाद की उपस्थिति का संकेत;
- एक नए अपवाद की पीढ़ी अगर अपवाद DLL की तरफ से पकड़ा गया था (अपवाद के प्रकार के बारे में विवरण और जानकारी की बहाली के साथ)।
DL_LIBRARY( name ) ( ( ret_type, name, arguments ) )
DL_LIBRARY मैक्रो द्वारा उत्पन्न कक्षाएं DLL सीमाओं के पार नहीं जा सकतीं।मैक्रो कैसे काम करता है, यह प्रदर्शित करने के लिए, निम्नलिखित हेडर फ़ाइल की कल्पना करें:
इस विवरण का उपयोग
DL_ डेवलपर द्वारा
DL_EXPORT मैक्रो के माध्यम से फ़ंक्शन को निर्यात करने के लिए किया जाता है। Test1_lib.hpp हेडर फ़ाइल को कनेक्ट करके, उपयोगकर्ता तुरंत DLL के साथ काम करना शुरू कर सकता है:
DL_EXPORT
DL_EXPORT मैक्रो DLL फ़ंक्शन को निर्यात करने के लिए डिज़ाइन किया गया है।
DL_EXPORT (
lib_class ,
lib_impl_class )
- lib_class - इंटरैक्शन इंटरफ़ेस का वर्णन करने वाले वर्ग का पूरा नाम (DL_LIBRARY में उपयोग किया जाने वाला वर्ग नाम);
- lib_impl_class इंटरेक्शन इंटरफ़ेस में निर्दिष्ट कार्यों को लागू करने वाले वर्ग का पूरी तरह से योग्य वर्ग नाम है।
DLL फ़ंक्शन निर्यात करने के लिए, आपको निम्न करना होगा:
- एक वर्ग (संरचना) बनाएँ;
- इंटरफ़ेस से प्रत्येक फ़ंक्शन को स्थिर के रूप में परिभाषित करें। कार्यक्षेत्र सार्वजनिक होना चाहिए :;
- DL_EXPORT (lib, impl) निर्माण लिखकर निर्यात कार्य करें।
उदाहरण के लिए, DL_LIBRARY विवरण में परिभाषित फ़ाइल
test1_lib.hpp में एक इंटरफ़ेस के लिए DLL कार्यान्वयन की कल्पना करें।
DL_INTERFACE
मैक्रो आपको क्लास इंटरफ़ेस का वर्णन करने और उपयोगकर्ता को इसके साथ काम करने के लिए एक रैपर क्लास प्रदान करने की अनुमति देता है। आवरण वर्ग का कार्यान्वयन C ++ अपवादों का सही उपयोग सुनिश्चित करता है:
- डीएलएल के पक्ष में सी ++ अपवादों का स्वत: पकड़;
- डीएलएल की सीमाओं के माध्यम से मूल्य की वापसी, एक अपवाद की उपस्थिति का संकेत;
- एक नए अपवाद की पीढ़ी अगर अपवाद DLL की तरफ से पकड़ा गया था (अपवाद के प्रकार के बारे में विवरण और जानकारी की बहाली के साथ)।
इस मैक्रो द्वारा उत्पन्न रैपर क्लास ने एक ऑब्जेक्ट का स्वामित्व साझा किया है जो इस इंटरफ़ेस को लागू करता है। साझा स्वामित्व एक लिंक गिनती तंत्र द्वारा प्रदान किया जाता है, अर्थात। आवरण वर्ग की वस्तुओं की प्रतिलिपि बनाते समय, संदर्भ काउंटर को बढ़ाने के लिए एक आंतरिक फ़ंक्शन को कहा जाता है; जब नष्ट हो जाता है, तो संदर्भ काउंटर को कम करने के लिए एक आंतरिक फ़ंक्शन कहा जाता है। जब काउंटर 0 पर पहुंच जाता है, तो ऑब्जेक्ट स्वचालित रूप से हटा दिया जाता है। इंटरफ़ेस विधियों तक पहुंच 'के माध्यम से है।' या '->'।
DynLib पुस्तकालय EXE सीमा (DLL) <-> DLL पर इंटरफ़ेस वर्गों के सुरक्षित उपयोग की गारंटी देता है DL_INTERFACE( interface_class ) ( ( ret_type, name, arguments ) )
- इंटरफ़ेस_क्लास - उस वर्ग का नाम जिसके कार्यान्वयन से डायनलिब लाइब्रेरी उत्पन्न होती है;
- विधियाँ - वर्ग इंटरफ़ेस का वर्णन करने वाले कार्यों की गणना,
एक उदाहरण:
DL_NS_BLOCK(( example ) ( DL_INTERFACE( processor ) ( ( int, threads_count, () ) ( void, process, (char const*,buf)(std::size_t,size) ) ) ))
का उपयोग करें:
example::processor p; p =…
dl :: साझा किया गया
टेम्पलेट वर्ग dl :: साझा <T> निम्नलिखित समस्याओं को हल करता है:
- निर्माणकर्ता में पारित तर्कों के साथ कक्षा टी की एक वस्तु का गतिशील निर्माण;
- एक संदर्भ काउंटर जोड़ना और साझा स्वामित्व प्रदान करना (जैसे बूस्ट (std) :: share_ptr);
- DL_INTERFACE मैक्रो द्वारा उत्पन्न वर्ग ऑब्जेक्ट को अंतर्निहित कास्टिंग।
कक्षा T के सदस्य कार्यों तक पहुँच '->' के माध्यम से है।
डीएल :: साझा कक्षाएं डीएलएल सीमाओं के पार नहीं जा सकतीं ।
मान लीजिए कि एक वर्ग
my_processor है और एक
उदाहरण :: प्रोसेसर इंटरफ़ेस:
class my_processor { public: my_processor( char const* name = "default name" ); int threads_count(); void process(char const* buf, std::size_t size); private:
Dl :: साझा का उपयोग करने के उदाहरण नीचे प्रस्तुत किए गए हैं:
dl::shared<my_processor> p1( "some processor name" );
dl :: रेफ
लाइब्रेरी फ़ंक्शन जो आपको
DL_INTERFACE के माध्यम से घोषित इंटरफ़ेस वर्ग के ऑब्जेक्ट के किसी ऑब्जेक्ट को समान सेट के साथ डालने की अनुमति देता है। आमतौर पर, यह व्यवहार आवश्यक है जब एक फ़ंक्शन होता है जो एक तर्क के रूप में एक इंटरफ़ेस क्लास लेता है, और आपको इसे एक ऑब्जेक्ट पास करना चाहिए जो स्टैक पर रखा गया है।
इंटरफेस के ऑब्जेक्ट्स के बाद से
dl :: ref फ़ंक्शन का उपयोग सावधानी से करना आवश्यक है, क्योंकि इस मामले में, स्थानांतरित ऑब्जेक्ट्स के स्वामी नहीं होंगे, और उपयोगकर्ता का ऑब्जेक्ट के जीवनकाल और इंटरफ़ेस कक्षाओं के माध्यम से इसके उपयोग पर नियंत्रण होता है। इंटरफ़ेस वर्गों की वस्तुओं को कॉपी करना जो
dl :: ref के माध्यम से पारित की गई वस्तुओं को संदर्भित करता है और काफी सही है (क्योंकि कोई संदर्भ काउंटर नहीं है, बदलने के लिए कुछ भी नहीं है - इंटरफ़ेस कक्षाओं की वस्तुओं को पता है कि यहां कैसे सही तरीके से काम करना है)।
class my_processor { public: my_processor( char const* name = "default name" ); int threads_count(); void process( char const* buf, std::size_t size ); private:
समर्थित कम्पाइलर
DynLib लाइब्रेरी निम्नलिखित कंपाइलर (विकास वातावरण) के साथ पूरी तरह से संगत है:
- Microsoft Visual C ++ 2008;
- Microsoft Visual C ++ 2010;
- न्यूनतम जीसीसी 4.5.0 और उच्चतर।
निम्नलिखित संकलक (विकास वातावरण) के साथ आंशिक रूप से संगत:
- कोडगियर सी ++ बिल्डर एक्सई (कुछ संकलक सेटिंग्स के तहत ऑपरेशन की गारंटी नहीं है)
लाइब्रेरी को यहां ले जाएं