सी ++ के साथ कई पोर्टेबिलिटी मुद्दे हैं, जो केवल द्विआधारी स्तर पर मानकीकरण की कमी के कारण है।
मुझे नहीं लगता कि यह काफी सरल है। प्रदान किए गए जवाब पहले से ही मानकीकरण पर ध्यान केंद्रित करने की कमी के रूप में उत्कृष्ट तर्क प्रदान करते हैं, लेकिन C ++ एक एबीआई मानक के रूप में सी के साथ अच्छी तरह से प्रतिस्पर्धा करने के लिए एक भाषा के लिए बहुत समृद्ध हो सकता है ।
हम फंक्शन ओवरलोडिंग, वाइबल असंगतताओं, मॉड्यूल सीमाओं के पार फेंकने वाले अपवादों के साथ असंगतता आदि के कारण नामकरण में जा सकते हैं। ये सभी एक वास्तविक दर्द हैं, और मैं चाहता हूं कि वे कम से कम वाइब्रेट लेआउट को मानकीकृत कर सकें।
लेकिन एक ABI मानक केवल एक संकलक में निर्मित C ++ dylibs बनाने के बारे में नहीं है, जो एक अलग संकलक द्वारा निर्मित दूसरे बाइनरी द्वारा उपयोग किए जाने में सक्षम है। ABI का उपयोग क्रॉस-लैंग्वेज में किया जाता है । यह अच्छा होगा यदि वे कम से कम पहले भाग को कवर कर सकते हैं, लेकिन ऐसा कोई तरीका नहीं है कि मैं सी ++ को कभी भी वास्तव में सी के साथ प्रतिस्पर्धा कर पाऊं जो सार्वभौमिक एबीआई स्तर की सबसे व्यापक रूप से-संगत dylibs बनाने के लिए बहुत महत्वपूर्ण है।
इस तरह निर्यात किए गए कार्यों की एक सरल जोड़ी की कल्पना करें:
void f(Foo foo);
void f(Bar bar, int val);
... और कल्पना कीजिए Foo
और Bar
श्रेणीबद्ध कन्स्ट्रक्टरों के साथ वर्ग थे, रचनाकारों की प्रतिलिपि बनाएँ, कंस्ट्रक्टरों को स्थानांतरित करें, और गैर-तुच्छ विध्वंसक।
फिर एक पायथन / लुआ / सी # / जावा / हास्केल / आदि का परिदृश्य लें। डेवलपर इस मॉड्यूल को आयात करने और इसे अपनी भाषा में उपयोग करने की कोशिश कर रहा है।
पहले हमें फ़ंक्शन ओवरलोडिंग के उपयोग के प्रतीकों को निर्यात करने के लिए मानक नाम के मानक की आवश्यकता होगी। यह एक आसान हिस्सा है। अभी तक यह वास्तव में नाम "mangling" नहीं होना चाहिए। चूंकि डिलिब के उपयोगकर्ताओं को नामों के आधार पर प्रतीकों को देखना पड़ता है, इसलिए यहां के अधिभार को उन नामों की ओर ले जाना चाहिए जो एक पूर्ण गड़बड़ी की तरह नहीं दिखते हैं। हो सकता है कि प्रतीक नाम उस तरह के "f_Foo"
"f_Bar_int"
या कुछ और हो सकते हैं । हमें यह सुनिश्चित करना होगा कि वे वास्तव में डेवलपर द्वारा परिभाषित एक नाम के साथ टकरा नहीं सकते हैं, शायद एबीआई उपयोग के लिए कुछ प्रतीकों / वर्णों / सम्मेलनों को संग्रहीत करते हैं।
लेकिन अब एक कठिन परिदृश्य। उदाहरण के लिए, पायथन डेवलपर कैसे चलता है, बिल्ड कंस्ट्रक्टर्स, कॉपी कंस्ट्रक्टर्स और डिस्ट्रक्टर्स को स्थानांतरित करता है? शायद हम dylib के हिस्से के रूप में निर्यात कर सकते हैं। लेकिन क्या होगा Foo
और अगर Bar
विभिन्न मॉड्यूल में निर्यात किया जाता है? क्या हमें इस dylib में जुड़े प्रतीकों और कार्यान्वयनों की नकल करनी चाहिए या नहीं? मेरा सुझाव है कि हम ऐसा करते हैं, क्योंकि यह वास्तव में बहुत तेजी से कष्टप्रद हो सकता है अन्यथा केवल एक वस्तु बनाने के लिए कई dylib इंटरफेस में उलझ जाना शुरू हो सकता है, इसे यहां पास करें, एक को कॉपी करें, यहां इसे नष्ट करें। जबकि एक ही मूल चिंता कुछ हद तक सी (बस अधिक मैन्युअल रूप से / स्पष्ट रूप से) में लागू हो सकती है, सी केवल इस तरह से लोगों के साथ कार्यक्रम करने की प्रकृति से बचने के लिए जाता है।
यह अजीबता का सिर्फ एक छोटा सा नमूना है। क्या होता है जब f
ऊपर दिए गए फंक्शन्स में से कोई एक BazException
(जावास्क्रिप्ट के साथ एक C ++ क्लास भी कंस्ट्रक्टर्स और डिस्ट्रक्टर्स और व्युत्पन्न std :: अपवाद) के रूप में फेंकता है ?
सबसे अच्छा मुझे लगता है कि हम केवल एक एबीआई को मानकीकृत करने की आशा कर सकते हैं जो एक सी + + संकलक द्वारा उत्पादित एक बाइनरी से दूसरे द्वारा उत्पादित बाइनरी से काम करता है। यह निश्चित रूप से बहुत अच्छा होगा, लेकिन मैं सिर्फ यह बताना चाहता था। आमतौर पर एक सामान्यीकृत पुस्तकालय को वितरित करने के लिए ऐसी चिंताओं के साथ जो क्रॉस-कंपाइलर का काम करता है, अक्सर इसे वास्तव में सामान्यीकृत और संगत क्रॉस-भाषा बनाने की इच्छा भी होती है।
सुझाया हुआ समाधान
COM- शैली इंटरफेस के साथ सालों से API / ABI के लिए C ++ इंटरफेस का उपयोग करने के तरीके खोजने के लिए संघर्ष करने के बाद मेरा सुझाया गया समाधान सिर्फ "C / C ++" (सज़ा) डेवलपर बनना है।
कार्यान्वयन के लिए C ++ के साथ, उन सार्वभौमिक ABI को बनाने के लिए C का उपयोग करें। हम अभी भी निर्यात कार्यों की तरह काम कर सकते हैं जो ढेर पर इस तरह की वस्तुओं को बनाने और नष्ट करने के लिए स्पष्ट कार्यों के साथ अपारदर्शी सी ++ वर्गों को पॉइंटर्स लौटाते हैं। अगर हम पूरी तरह से कार्यान्वयन के लिए C ++ का उपयोग कर रहे हैं, तब भी ABI के दृष्टिकोण से उस C सौंदर्यबोध से प्यार करने की कोशिश करें। फ़ंक्शन इंटरफेस के तालिकाओं का उपयोग करके सार इंटरफेस को मॉडलिंग किया जा सकता है। इस सामान को C API में लपेटना थकाऊ है, लेकिन इसके साथ मिलने वाले वितरण के लाभ और अनुकूलता इसे बहुत सार्थक बना देंगे।
फिर अगर हम इस इंटरफ़ेस का सीधे तौर पर उपयोग करना पसंद नहीं करते हैं (हम शायद कम से कम RAII कारणों के लिए नहीं करना चाहिए), तो हम इसे एसडीके के साथ हम एक वैधानिक रूप से जुड़े सी ++ लाइब्रेरी में हम सभी को लपेट सकते हैं। C ++ क्लाइंट इसका उपयोग कर सकते हैं।
अजगर ग्राहक सीधे सी या सी ++ इंटरफ़ेस का उपयोग नहीं करना चाहेंगे क्योंकि उन अजगर को बनाने का कोई तरीका नहीं है। वे इसे अपने पाइथनिक इंटरफेस में लपेटना चाहते हैं, इसलिए यह वास्तव में एक अच्छी बात है कि हम नंगे न्यूनतम सी एपीआई / एबीआई का निर्यात कर रहे हैं ताकि यह यथासंभव आसान हो सके।
मुझे लगता है कि C ++ उद्योग के बहुत सारे लोग COM- शैली के इंटरफेस और इसके बाद के कड़े प्रयास करने के बजाय इसे और अधिक करने से लाभान्वित होंगे। यह हमारे सभी जीवन को आसान बना देगा क्योंकि इन dylibs के उपयोगकर्ताओं को अजीब एबीआई के साथ उपद्रव नहीं करना चाहिए। C इसे सरल बनाता है, और ABI के दृष्टिकोण से इसकी सादगी हमें API / ABI बनाने की अनुमति देती है जो सभी प्रकार के FFI के लिए स्वाभाविक रूप से और अतिसूक्ष्मवाद के साथ काम करते हैं।