जावा नेटिव इंटरफ़ेस: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
{{Short description|Foreign function interface}} | {{Short description|Foreign function interface}} | ||
{{Redirect| | {{Redirect|जेएनआई}}[[सॉफ्टवेर डिज़ाइन]] में, जावा नेटिव इंटरफ़ेस (जेएनआई) [[विदेशी फ़ंक्शन इंटरफ़ेस]] प्रोग्रामिंग [[सॉफ्टवेयर ढांचा|सॉफ्टवेयर रुपरेखा]] है जो [[जावा वर्चुअल मशीन]] (जेवीएम) में चलने वाले [[जावा (प्रोग्रामिंग भाषा)]] कोड को कॉल करने और कॉल करने में सक्षम बनाता है।<ref name="role">{{cite web |url=https://docs.oracle.com/en/java/javase/11/docs/specs/jni/intro.html#java-native-interface-overview |title=जावा नेटिव इंटरफ़ेस अवलोकन|access-date=2018-12-27 |work= The Java Native Interface Programmer's Guide and Specification}} | ||
</ref> मूल एप्लिकेशन (हार्डवेयर और [[ऑपरेटिंग सिस्टम]] प्लेटफ़ॉर्म के लिए विशिष्ट प्रोग्राम) और [[लाइब्रेरी (कंप्यूटिंग)]] अन्य भाषाओं जैसे C (प्रोग्रामिंग भाषा), [[C++]] और असेंबली भाषा में लिखे गए हैं। | </ref> मूल एप्लिकेशन (हार्डवेयर और [[ऑपरेटिंग सिस्टम]] प्लेटफ़ॉर्म के लिए विशिष्ट प्रोग्राम) और [[लाइब्रेरी (कंप्यूटिंग)]] अन्य भाषाओं जैसे C (प्रोग्रामिंग भाषा), [[C++]] और असेंबली भाषा में लिखे गए हैं। | ||
== उद्देश्य == | == उद्देश्य == | ||
जेएनआई प्रोग्रामर्स को उन स्थितियों को संभालने के लिए मूल | जेएनआई प्रोग्रामर्स को उन स्थितियों को संभालने के लिए मूल विधियों को लिखने में सक्षम बनाता है जब कोई एप्लिकेशन पूरी तरह से जावा प्रोग्रामिंग भाषा में नहीं लिखा जा सकता है, उदाहरण के लिए जब मानक जावा क्लास (कंप्यूटर विज्ञान) लाइब्रेरी (कंप्यूटर विज्ञान) प्लेटफ़ॉर्म-विशिष्ट सुविधाओं या प्रोग्राम लाइब्रेरी का समर्थन नहीं करता है। इसका उपयोग किसी वर्तमान एप्लिकेशन (किसी अन्य प्रोग्रामिंग भाषा में लिखा गया) को संशोधित करने के लिए भी किया जाता है जिससे उसे जावा अनुप्रयोगों तक पहुंच योग्य बनाया जा सकता है। कई मानक लाइब्रेरी कक्षाएं डेवलपर और उपयोगकर्ता को कार्यक्षमता प्रदान करने के लिए जेएनआई पर निर्भर करती हैं, उदाहरण के लिए फ़ाइल I/O और ध्वनि क्षमताएं मानक लाइब्रेरी में प्रदर्शन- और प्लेटफ़ॉर्म-संवेदनशील एपीआई कार्यान्वयन सम्मिलित करने से सभी जावा एप्लिकेशन इस कार्यक्षमता को सुरक्षित और प्लेटफ़ॉर्म-स्वतंत्र विधि से एक्सेस कर सकते हैं। | ||
जेएनआई फ्रेमवर्क मूल विधि को जावा ऑब्जेक्ट (कंप्यूटर विज्ञान) का उसी तरह उपयोग करने देता है जैसे जावा कोड इन ऑब्जेक्ट का उपयोग करता है। मूल विधि जावा ऑब्जेक्ट बना सकती है और फिर अपने कार्यों को करने के लिए इन ऑब्जेक्ट का निरीक्षण और उपयोग कर सकती है। मूल विधि जावा एप्लिकेशन कोड द्वारा बनाई गई वस्तुओं का निरीक्षण और उपयोग भी कर सकती है। | जेएनआई फ्रेमवर्क मूल विधि को जावा ऑब्जेक्ट (कंप्यूटर विज्ञान) का उसी तरह उपयोग करने देता है जैसे जावा कोड इन ऑब्जेक्ट का उपयोग करता है। मूल विधि जावा ऑब्जेक्ट बना सकती है और फिर अपने कार्यों को करने के लिए इन ऑब्जेक्ट का निरीक्षण और उपयोग कर सकती है। मूल विधि जावा एप्लिकेशन कोड द्वारा बनाई गई वस्तुओं का निरीक्षण और उपयोग भी कर सकती है। | ||
केवल एप्लिकेशन और हस्ताक्षरित एप्लेट ही जेएनआई को | केवल एप्लिकेशन और हस्ताक्षरित एप्लेट ही जेएनआई को प्रयुक्त कर सकते हैं। | ||
एक एप्लिकेशन जो जेएनआई पर निर्भर करता है वह जावा द्वारा प्रदान की जाने वाली प्लेटफ़ॉर्म पोर्टेबिलिटी खो देता है (एक आंशिक समाधान यह है कि प्रत्येक प्लेटफ़ॉर्म के लिए जेएनआई कोड का अलग कार्यान्वयन लिखा जाए और जावा ऑपरेटिंग सिस्टम का पता लगाए और रनटाइम पर सही लोड करे)। | एक एप्लिकेशन जो जेएनआई पर निर्भर करता है वह जावा द्वारा प्रदान की जाने वाली प्लेटफ़ॉर्म पोर्टेबिलिटी खो देता है (एक आंशिक समाधान यह है कि प्रत्येक प्लेटफ़ॉर्म के लिए जेएनआई कोड का अलग कार्यान्वयन लिखा जाए और जावा ऑपरेटिंग सिस्टम का पता लगाए और रनटाइम पर सही लोड करे)। | ||
इस प्नकार केवल मूल कोड जावा के साथ इंटरफ़ेस कर सकता है, किन्तु यह जावा पर आरेखण भी कर सकता है {{Javadoc:SE|java/awt|कैनवास|module=java.desktop}}, जो जावा एडब्ल्यूटी नेटिव इंटरफ़ेस के साथ संभव है। प्रक्रिया लगभग वही है, बस कुछ बदलावों के साथ जावा एडब्ल्यूटी नेटिव इंटरफ़ेस केवल जावा प्लेटफ़ॉर्म, मानक संस्करण 1.3 के बाद से उपलब्ध है। | |||
जेएनआई सी (प्रोग्रामिंग भाषा) ब्रिज से | जेएनआई सी (प्रोग्रामिंग भाषा) ब्रिज से निकले बिना भी असेंबली भाषा तक सीधी पहुंच की अनुमति देता है।<ref>{{cite web | url = http://today.java.net/pub/a/today/2006/10/19/invoking-assembly-language-from-java.html | title = जावा से असेंबली लैंग्वेज प्रोग्राम को लागू करना| publisher = Java.net | date = 2006-10-19 | access-date = 2007-10-06 | url-status = dead | archive-url = https://web.archive.org/web/20080330002620/http://today.java.net/pub/a/today/2006/10/19/invoking-assembly-language-from-java.html | archive-date = 2008-03-30 }}</ref> असेंबली से जावा एप्लिकेशन तक पहुंच उसी तरह संभव है।<ref>{{ cite web | url = http://today.java.net/pub/a/today/2007/10/04/launch-java-applications-from-assembly-language-programs.html | title = असेंबली लैंग्वेज प्रोग्राम से जावा एप्लिकेशन लॉन्च करें| publisher = Java.net | date = 2006-10-19 | access-date = 2007-10-04 | url-status = dead | archive-url = https://web.archive.org/web/20071011014140/http://today.java.net/pub/a/today/2007/10/04/launch-java-applications-from-assembly-language-programs.html | archive-date = 2007-10-11 }}</ref> | ||
== डिज़ाइन == | == डिज़ाइन == | ||
जेएनआई | जेएनआई रुपरेखा में, मूल कार्यों को अलग-अलग .c या .cpp फ़ाइलों में प्रयुक्त किया जाता है। (C++ JNI के साथ थोड़ा सरल इंटरफ़ेस प्रदान करता है।) जब जेवीएम फ़ंक्शन को इनवॉइस करता है, तो यह पास करता है <code>JNIEnv</code> सूचक, ए <code>jobject</code> सूचक, और जावा विधि द्वारा घोषित कोई भी जावा तर्क उदाहरण के लिए, निम्नलिखित जावा स्ट्रिंग को मूल स्ट्रिंग में परिवर्तित करता है: | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
Line 32: | Line 32: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<code>env</code>पॉइंटर संरचना है जिसमें | <code>env</code>पॉइंटर संरचना है जिसमें जेवीएम का इंटरफ़ेस होता है। इसमें जेवीएम के साथ इंटरैक्ट करने और जावा ऑब्जेक्ट के साथ काम करने के लिए आवश्यक सभी फ़ंक्शन सम्मिलित हैं। उदाहरण जेएनआई फ़ंक्शंस मूल सरणी को जावा सरणी से/से परिवर्तित कर रहे हैं, मूल स्ट्रिंग को जावा स्ट्रिंग से/से परिवर्तित कर रहे हैं, ऑब्जेक्ट्स को इंस्टेंटियेट कर रहे हैं, अपवाद फेंक रहे हैं, आदि मूल रूप से, जावा कोड जो कुछ भी कर सकता है उसका उपयोग <code>JNIEnv</code> करके किया जा सकता है , | ||
तर्क<code>obj</code>जावा ऑब्जेक्ट का संदर्भ है जिसके अंदर यह मूल विधि घोषित की गई है। | तर्क<code>obj</code>जावा ऑब्जेक्ट का संदर्भ है जिसके अंदर यह मूल विधि घोषित की गई है। | ||
मूल [[डेटा प्रकार]] | मूल [[डेटा प्रकार]] को जावा डेटा प्रकारों से मैप किया जा सकता है। वस्तुओं, ऐरे डेटा संरचना और [[स्ट्रिंग (कंप्यूटर विज्ञान)]] जैसे यौगिक प्रकारों के लिए मूल कोड को स्पष्ट रूप से कॉल विधियों द्वारा डेटा <code>JNIEnv</code> को परिवर्तित करना होता है | ||
. | |||
एक जेएनआई पर्यावरण सूचक ({{mono|JNIEnv*}}) को जावा विधि में मैप किए गए प्रत्येक मूल फ़ंक्शन के लिए तर्क के रूप में पारित किया जाता है, जो मूल विधि के अन्दर जेएनआई वातावरण के साथ वार्तालाप की अनुमति देता है। यह जेएनआई इंटरफ़ेस पॉइंटर संग्रहीत किया जा सकता है, किन्तु केवल वर्तमान थ्रेड में ही मान्य रहता है। अन्य थ्रेड्स को पहले कॉल करना होगा {{mono|AttachCurrentThread()}} स्वयं को वीएम से जोड़ने और जेएनआई इंटरफ़ेस पॉइंटर प्राप्त करने के लिए। बार संलग्न होने के बाद, मूल थ्रेड मूल विधि के अन्दर चलने वाले नियमित जावा थ्रेड की तरह काम करता है। मूल थ्रेड वीएम से तब तक जुड़ा रहता है जब तक वह कॉल नहीं करता {{mono|DetachCurrentThread()}}स्वयं को अलग करने के लिए.<ref>The Invocation API. Sun Microsystems. https://docs.oracle.com/en/java/javase/11/docs/specs/jni/invocation.html</ref> | |||
जेएनआई रुपरेखा मूल पक्ष पर कोड निष्पादन द्वारा आवंटित गैर-जेवीएम मेमोरी संसाधनों के लिए कोई स्वचालित कचरा संग्रहण प्रदान नहीं करता है। परिणाम स्वरुप, नेटिव साइड कोड (जैसे असेंबली लैंग्वेज) नेटिव कोड द्वारा प्राप्त ऐसे किसी भी मेमोरी संसाधन को स्पष्ट रूप से जारी करने की उत्तरदायी लेता है। | |||
लिनक्स और सोलारिस प्लेटफ़ॉर्म पर, यदि मूल कोड स्वयं को सिग्नल हैंडलर के रूप में पंजीकृत करता है, तो यह जेवीएम के लिए इच्छित सिग्नल को रोक सकता है। मूल कोड को जेवीएम के साथ उत्तम विधि से संचालित करने की अनुमति देने के लिए [[ज़िम्मेदारी की शृंखला|उत्तरदायी की शृंखला]] का उपयोग किया जा सकता है। विंडोज़ प्लेटफ़ॉर्म पर, माइक्रोसॉफ्ट-विशिष्ट अपवाद हैंडलिंग तंत्र या संरचित अपवाद हैंडलिंग या संरचित अपवाद हैंडलिंग (एसईएच) को एसईएच प्रयास/पकड़ ब्लॉक में मूल कोड को लपेटने के लिए नियोजित किया जा सकता है जिससे मशीन (सीपीयू/एफपीयू) उत्पन्न सॉफ़्टवेयर इंटरप्ट (जैसे) को कैप्चर किया जा सके व्यर्थ पॉइंटर एक्सेस उल्लंघन और डिवाइड-बाय-ज़ीरो ऑपरेशंस), और जेवीएम (अर्थात जावा साइड कोड) में बाधा उत्पन्न होने से पहले इन स्थितियों को संभालने के लिए, सभी संभावनाओं में जिसके परिणामस्वरूप अनचाहे अपवाद हो सकता है। | |||
न्यूस्ट्रिंगयूटीएफ, गेटस्ट्रिंग यूटीएफलेंथ, गेटस्ट्रिंग यूटीएफचार्स,रिलीजस्ट्रिंग यूटीएफचर्स और गेटस्ट्रिंगयूटीएफक्षेत्र फ़ंक्शंस के लिए उपयोग की जाने वाली एन्कोडिंग को यूटीएफ-8 संशोधित किया गया है।<ref name="jniModifiedUtf">{{cite web|url=http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/types.html#wp16542|title=JNI Types and Data Structures}}</ref> जो सभी इनपुट के लिए मान्य यूटीएफ-8 नहीं है, किन्तु वास्तव में अलग एन्कोडिंग है। शून्य वर्ण (U+0000) और कोडप्वाइंट जो प्लेन (यूनिकोड) या बेसिक मल्टीलिंगुअल प्लेन पर नहीं हैं (U+10000 से अधिक या उसके बराबर, अर्थात जिन्हें यूटीएफ-16 में सरोगेट जोड़े के रूप में दर्शाया गया है) को संशोधित यूटीएफ-8 में अलग-अलग विधि से एन्कोड किया गया है। कई प्रोग्राम वास्तव में इन फ़ंक्शंस का गलत विधि से उपयोग करते हैं और संशोधित यूटीएफ -8 स्ट्रिंग्स के अतिरिक्त मानक यूटीएफ -8 स्ट्रिंग्स के रूप में लौटाए गए या फ़ंक्शन में पास किए गए यूटीएफ -8 स्ट्रिंग्स का इलाज करते हैं। प्रोग्राम को न्यूस्ट्रिंग, गेटस्ट्रिंगलेंथ, गेटस्ट्रिंगचार्स, रिलीजस्ट्रिंगचार्स, गेटस्ट्रिंगरीजन, गेटस्ट्रिंगक्रिटिकल और रिलीजस्ट्रिंगक्रिटिकल फ़ंक्शंस का उपयोग करना चाहिए, जो छोटे-एंडियन आर्किटेक्चर पर यूटीएफ-16एल.ई एन्कोडिंग और बड़े-एंडियन आर्किटेक्चर पर यूटीएफ-16बीई का उपयोग करते हैं, और फिर यूटीएफ-16 से यूटीएफ- का उपयोग करते हैं। | |||
== मानचित्रण प्रकार == | == मानचित्रण प्रकार == | ||
Line 49: | Line 52: | ||
{| class="wikitable" | {| class="wikitable" | ||
! | !सी टाइप | ||
! | !जावा भाषा प्रकार | ||
! | !विवरण | ||
! | !हस्ताक्षर टाइप करें | ||
|- | |- | ||
| | |अचिन्हित वर्ण | ||
| | यूइंट8_t | ||
| | |जबूलियन | ||
|अहस्ताक्षरित 8 बिट्स | |||
|Z | |Z | ||
|- | |- | ||
| | |हस्ताक्षरित चार | ||
| | int8_t | ||
| | |जेबाइट | ||
|अहस्ताक्षरित 8 बिट्स | |||
|B | |B | ||
|- | |- | ||
| | |अहस्ताक्षरित लघु | ||
| | uint16_t | ||
|unsigned 16 | |जचर | ||
|unsigned 16 बिट्स | |||
|C | |C | ||
|- | |- | ||
| | |छोटा | ||
| | int16_t | ||
| | |जेशॉर्ट | ||
|अहस्ताक्षरित 16 बिट्स | |||
|S | |S | ||
|- | |- | ||
| | |पूर्णांक | ||
| | int32_टी | ||
| | |जिन्ट | ||
|अहस्ताक्षरित 32 बिट्स | |||
|I | |I | ||
|- | |- | ||
| | | | ||
लम्बा लम्बा | |||
| | |||
| | int64_टी | ||
|ज्लॉन्ग | |||
|अहस्ताक्षरित 64 बिट्स | |||
|J | |J | ||
|- | |- | ||
| | |फ्लोट | ||
| | |जेफ़्लोट | ||
|32 | |32 बिट्स | ||
|F | |F | ||
|- | |- | ||
| | |डबल | ||
| | |जेडबल | ||
|64 | |64 बिट्स | ||
|D | |D | ||
|- | |- | ||
| | |रिक्त | ||
| | | | ||
| | | | ||
|V | |V | ||
|} | |} | ||
इसके | इसके अतिरिक्त, हस्ताक्षर <code>"L {{Sic|hide=y|fully|-}}qualified-class ;"</code> इसका कारण उस नाम से विशिष्ट रूप से निर्दिष्ट वर्ग होता है; उदाहरण के लिए, हस्ताक्षर <code>"Ljava/lang/String;"</code> वर्ग को संदर्भित करता है <code>java.lang.String</code>. इसके अतिरिक्त, उपसर्ग हस्ताक्षर करने के लिए उस प्रकार की सरणी बनाता है; उदाहरण के लिए, <code>[I</code> कारण int सारणी प्रकार अंततः, ए <code>void</code> हस्ताक्षर का उपयोग करता है | ||
ये प्रकार विनिमेय हैं। कोई भी प्रयोग कर सकता है <code>jint</code> जहां आप | ये प्रकार विनिमेय हैं। कोई भी प्रयोग कर सकता है <code>jint</code> जहां आप सामान्यतः का उपयोग करते हैं <code>int</code>, और इसके विपरीत, बिना किसी प्रकार के रूपांतरण की आवश्यकता के। चूँकि, जावा स्ट्रिंग्स और एरे के बीच देशी स्ट्रिंग्स और एरे के बीच मैपिंग अलग है। यदि <code>jstring</code> इसका प्रयोग वहां किया जाता है जहां a <code>char *</code> होता है, कोड जेवीएम को क्रैश कर सकता है। | ||
== प्रदर्शन == | == प्रदर्शन == | ||
कुछ परिस्थितियों में जेएनआई को | कुछ परिस्थितियों में जेएनआई को अधिक ओवरहेड और प्रदर्शन हानि उठानी पड़ती है: <ref name= StackOverflow: जेएनआई कॉल धीमी क्यों होती है? >{{cite web|url=https://stackoverflow.com/a/7809300/1068537|title=जावा — जेएनआई कॉल धीमी क्यों होती है? - स्टैक ओवरफ़्लो}}</ref> | ||
* जेएनआई विधियों के लिए फ़ंक्शन कॉल महंगे हैं, | * जेएनआई विधियों के लिए फ़ंक्शन कॉल महंगे हैं, जब किसी विधि को बार-बार कॉल करना होता है। | ||
* मूल विधियाँ | * मूल विधियाँ जेवीएम द्वारा इनलाइन नहीं की जाती हैं, इस प्रकार न ही विधि [[बिल्कुल सही समय पर संकलन|जेआईटी संकलित]] हो सकती है, क्योंकि विधि पहले से ही संकलित है। | ||
* मूल कोड तक पहुंच के लिए जावा ऐरे को कॉपी किया जा सकता है, और बाद में वापस कॉपी किया जा सकता है। | * मूल कोड तक पहुंच के लिए जावा ऐरे को कॉपी किया जा सकता है, और बाद में वापस कॉपी किया जा सकता है। निवेश सरणी के आकार में रैखिक हो सकती है। | ||
* यदि विधि किसी ऑब्जेक्ट को पारित कर देती है, या कॉलबैक करने की आवश्यकता होती है, | * यदि विधि किसी ऑब्जेक्ट को पारित कर देती है, या कॉलबैक करने की आवश्यकता होती है, जिससे मूल विधि संभवतः जेवीएम पर अपनी कॉल कर रही होटी है। मूल कोड से जावा फ़ील्ड, विधियों और प्रकारों तक पहुंचने के लिए [[ प्रतिबिंब (कंप्यूटर प्रोग्रामिंग) |प्रतिबिंब (कंप्यूटर प्रोग्रामिंग)]] के समान कुछ की आवश्यकता होती है। हस्ताक्षर स्ट्रिंग्स में निर्दिष्ट किए जाते हैं और जेवीएम से पूछे जाते हैं। यह धीमा और त्रुटि-प्रवण दोनों है। | ||
* जावा स्ट्रिंग्स ऑब्जेक्ट हैं, लंबाई हैं और एन्कोडेड हैं। किसी स्ट्रिंग तक पहुँचने या बनाने के लिए O(n) प्रतिलिपि की आवश्यकता हो सकती है। | * जावा स्ट्रिंग्स ऑब्जेक्ट हैं, लंबाई हैं और एन्कोडेड हैं। किसी स्ट्रिंग तक पहुँचने या बनाने के लिए O(n) प्रतिलिपि की आवश्यकता हो सकती है। | ||
== विकल्प == | == विकल्प == | ||
माइक्रोसॉफ्ट के जावा वर्चुअल मशीन (विजुअल जे++) के | माइक्रोसॉफ्ट के जावा वर्चुअल मशीन (विजुअल जे++) के प्रोपर्टी कार्यान्वयन में जावा से मूल कोड को कॉल करने के लिए समान तंत्र था, जिसे रॉ नेटिव इंटरफ़ेस (आरएनआई) कहा जाता था। इसके अतिरिक्त, इसमें वर्तमान मूल कोड को कॉल करने का सरल विधि थी जो स्वयं जावा से अवगत नहीं था, जैसे कि विंडोज़ एपीआई, जिसे जे/डायरेक्ट कहा जाता है। चूँकि, इस कार्यान्वयन के बारे में J++ या सन-माइक्रोसॉफ्ट मुकदमे के विरुद्ध [[विज़ुअल J++]] का अब रखरखाव नहीं किया जाता है। | ||
जेएनआई की तुलना में आरएनआई का उपयोग कम अनाड़ी था, क्योंकि जावा पर्यावरण सूचक के साथ किसी बहीखाता की आवश्यकता नहीं थी। इसके | जेएनआई की तुलना में आरएनआई का उपयोग कम अनाड़ी था, क्योंकि जावा पर्यावरण सूचक के साथ किसी बहीखाता की आवश्यकता नहीं थी। इसके अतिरिक्त, सभी जावा ऑब्जेक्ट्स को सीधे एक्सेस किया जा सकता है। इसे सुविधाजनक बनाने के लिए, टूल का उपयोग किया गया जो जावा कक्षाओं से हेडर फ़ाइलें उत्पन्न करता था। इसी प्रकार, आवश्यक मध्यवर्ती देशी लाइब्रेरी और जेएनआई का उपयोग करने की तुलना में जे/डायरेक्ट का उपयोग करना सरल था। | ||
[[जावा नेटिव एक्सेस]] | [[जावा नेटिव एक्सेस]] (जेएनए) समुदाय-विकसित लाइब्रेरी है जो जावा प्रोग्रामर्स को जेएनआई का उपयोग किए बिना मूल साझा लाइब्रेरी तक सरल पहुंच प्रदान करती है। चूँकि, इसके लिए निर्भर जार लाइब्रेरी के पुनर्वितरण की आवश्यकता है। जेएनआई को कोड करना कठिन होने और जेएनए के धीमे होने के बीच समझौता है।<ref>{{cite web |last1=Zakusylo |first1=Alexander |title=Github मूल JNA स्रोत भी है। जेएनए बनाम जेएनआई बेंचमार्क गति परीक्षण|url=https://github.com/zakgof/java-native-benchmark |website=Github |publisher=Github |access-date=30 March 2023}}</ref> जेएनआई को कोर जावा में बनाया गया है। | ||
== यह भी देखें == | == यह भी देखें == | ||
* | * जीआईडब्ल्यूएस (सॉफ्टवेयर) | ||
* [[ग्लूजेन]] | * [[ग्लूजेन]] | ||
* [[प्लेटफ़ॉर्म मंगलाचरण सेवाएँ]] | * [[प्लेटफ़ॉर्म मंगलाचरण सेवाएँ]] | ||
* [[ बड़ा घूँट ]] | * [[ बड़ा घूँट |स्वाइग]] | ||
== संदर्भ == | == संदर्भ == | ||
{{reflist|30em}} | {{reflist|30em}} | ||
Revision as of 17:06, 3 July 2023
सॉफ्टवेर डिज़ाइन में, जावा नेटिव इंटरफ़ेस (जेएनआई) विदेशी फ़ंक्शन इंटरफ़ेस प्रोग्रामिंग सॉफ्टवेयर रुपरेखा है जो जावा वर्चुअल मशीन (जेवीएम) में चलने वाले जावा (प्रोग्रामिंग भाषा) कोड को कॉल करने और कॉल करने में सक्षम बनाता है।[1] मूल एप्लिकेशन (हार्डवेयर और ऑपरेटिंग सिस्टम प्लेटफ़ॉर्म के लिए विशिष्ट प्रोग्राम) और लाइब्रेरी (कंप्यूटिंग) अन्य भाषाओं जैसे C (प्रोग्रामिंग भाषा), C++ और असेंबली भाषा में लिखे गए हैं।
उद्देश्य
जेएनआई प्रोग्रामर्स को उन स्थितियों को संभालने के लिए मूल विधियों को लिखने में सक्षम बनाता है जब कोई एप्लिकेशन पूरी तरह से जावा प्रोग्रामिंग भाषा में नहीं लिखा जा सकता है, उदाहरण के लिए जब मानक जावा क्लास (कंप्यूटर विज्ञान) लाइब्रेरी (कंप्यूटर विज्ञान) प्लेटफ़ॉर्म-विशिष्ट सुविधाओं या प्रोग्राम लाइब्रेरी का समर्थन नहीं करता है। इसका उपयोग किसी वर्तमान एप्लिकेशन (किसी अन्य प्रोग्रामिंग भाषा में लिखा गया) को संशोधित करने के लिए भी किया जाता है जिससे उसे जावा अनुप्रयोगों तक पहुंच योग्य बनाया जा सकता है। कई मानक लाइब्रेरी कक्षाएं डेवलपर और उपयोगकर्ता को कार्यक्षमता प्रदान करने के लिए जेएनआई पर निर्भर करती हैं, उदाहरण के लिए फ़ाइल I/O और ध्वनि क्षमताएं मानक लाइब्रेरी में प्रदर्शन- और प्लेटफ़ॉर्म-संवेदनशील एपीआई कार्यान्वयन सम्मिलित करने से सभी जावा एप्लिकेशन इस कार्यक्षमता को सुरक्षित और प्लेटफ़ॉर्म-स्वतंत्र विधि से एक्सेस कर सकते हैं।
जेएनआई फ्रेमवर्क मूल विधि को जावा ऑब्जेक्ट (कंप्यूटर विज्ञान) का उसी तरह उपयोग करने देता है जैसे जावा कोड इन ऑब्जेक्ट का उपयोग करता है। मूल विधि जावा ऑब्जेक्ट बना सकती है और फिर अपने कार्यों को करने के लिए इन ऑब्जेक्ट का निरीक्षण और उपयोग कर सकती है। मूल विधि जावा एप्लिकेशन कोड द्वारा बनाई गई वस्तुओं का निरीक्षण और उपयोग भी कर सकती है।
केवल एप्लिकेशन और हस्ताक्षरित एप्लेट ही जेएनआई को प्रयुक्त कर सकते हैं।
एक एप्लिकेशन जो जेएनआई पर निर्भर करता है वह जावा द्वारा प्रदान की जाने वाली प्लेटफ़ॉर्म पोर्टेबिलिटी खो देता है (एक आंशिक समाधान यह है कि प्रत्येक प्लेटफ़ॉर्म के लिए जेएनआई कोड का अलग कार्यान्वयन लिखा जाए और जावा ऑपरेटिंग सिस्टम का पता लगाए और रनटाइम पर सही लोड करे)।
इस प्नकार केवल मूल कोड जावा के साथ इंटरफ़ेस कर सकता है, किन्तु यह जावा पर आरेखण भी कर सकता है कैनवास
, जो जावा एडब्ल्यूटी नेटिव इंटरफ़ेस के साथ संभव है। प्रक्रिया लगभग वही है, बस कुछ बदलावों के साथ जावा एडब्ल्यूटी नेटिव इंटरफ़ेस केवल जावा प्लेटफ़ॉर्म, मानक संस्करण 1.3 के बाद से उपलब्ध है।
जेएनआई सी (प्रोग्रामिंग भाषा) ब्रिज से निकले बिना भी असेंबली भाषा तक सीधी पहुंच की अनुमति देता है।[2] असेंबली से जावा एप्लिकेशन तक पहुंच उसी तरह संभव है।[3]
डिज़ाइन
जेएनआई रुपरेखा में, मूल कार्यों को अलग-अलग .c या .cpp फ़ाइलों में प्रयुक्त किया जाता है। (C++ JNI के साथ थोड़ा सरल इंटरफ़ेस प्रदान करता है।) जब जेवीएम फ़ंक्शन को इनवॉइस करता है, तो यह पास करता है JNIEnv
सूचक, ए jobject
सूचक, और जावा विधि द्वारा घोषित कोई भी जावा तर्क उदाहरण के लिए, निम्नलिखित जावा स्ट्रिंग को मूल स्ट्रिंग में परिवर्तित करता है:
extern "C"
JNIEXPORT void JNICALL Java_ClassName_MethodName
(JNIEnv *env, jobject obj, jstring javaString)
{
const char *nativeString = env->GetStringUTFChars(javaString, 0);
//Do something with the nativeString
env->ReleaseStringUTFChars(javaString, nativeString);
}
env
पॉइंटर संरचना है जिसमें जेवीएम का इंटरफ़ेस होता है। इसमें जेवीएम के साथ इंटरैक्ट करने और जावा ऑब्जेक्ट के साथ काम करने के लिए आवश्यक सभी फ़ंक्शन सम्मिलित हैं। उदाहरण जेएनआई फ़ंक्शंस मूल सरणी को जावा सरणी से/से परिवर्तित कर रहे हैं, मूल स्ट्रिंग को जावा स्ट्रिंग से/से परिवर्तित कर रहे हैं, ऑब्जेक्ट्स को इंस्टेंटियेट कर रहे हैं, अपवाद फेंक रहे हैं, आदि मूल रूप से, जावा कोड जो कुछ भी कर सकता है उसका उपयोग JNIEnv
करके किया जा सकता है ,
तर्कobj
जावा ऑब्जेक्ट का संदर्भ है जिसके अंदर यह मूल विधि घोषित की गई है।
मूल डेटा प्रकार को जावा डेटा प्रकारों से मैप किया जा सकता है। वस्तुओं, ऐरे डेटा संरचना और स्ट्रिंग (कंप्यूटर विज्ञान) जैसे यौगिक प्रकारों के लिए मूल कोड को स्पष्ट रूप से कॉल विधियों द्वारा डेटा JNIEnv
को परिवर्तित करना होता है
.
एक जेएनआई पर्यावरण सूचक (JNIEnv*) को जावा विधि में मैप किए गए प्रत्येक मूल फ़ंक्शन के लिए तर्क के रूप में पारित किया जाता है, जो मूल विधि के अन्दर जेएनआई वातावरण के साथ वार्तालाप की अनुमति देता है। यह जेएनआई इंटरफ़ेस पॉइंटर संग्रहीत किया जा सकता है, किन्तु केवल वर्तमान थ्रेड में ही मान्य रहता है। अन्य थ्रेड्स को पहले कॉल करना होगा AttachCurrentThread() स्वयं को वीएम से जोड़ने और जेएनआई इंटरफ़ेस पॉइंटर प्राप्त करने के लिए। बार संलग्न होने के बाद, मूल थ्रेड मूल विधि के अन्दर चलने वाले नियमित जावा थ्रेड की तरह काम करता है। मूल थ्रेड वीएम से तब तक जुड़ा रहता है जब तक वह कॉल नहीं करता DetachCurrentThread()स्वयं को अलग करने के लिए.[4]
जेएनआई रुपरेखा मूल पक्ष पर कोड निष्पादन द्वारा आवंटित गैर-जेवीएम मेमोरी संसाधनों के लिए कोई स्वचालित कचरा संग्रहण प्रदान नहीं करता है। परिणाम स्वरुप, नेटिव साइड कोड (जैसे असेंबली लैंग्वेज) नेटिव कोड द्वारा प्राप्त ऐसे किसी भी मेमोरी संसाधन को स्पष्ट रूप से जारी करने की उत्तरदायी लेता है।
लिनक्स और सोलारिस प्लेटफ़ॉर्म पर, यदि मूल कोड स्वयं को सिग्नल हैंडलर के रूप में पंजीकृत करता है, तो यह जेवीएम के लिए इच्छित सिग्नल को रोक सकता है। मूल कोड को जेवीएम के साथ उत्तम विधि से संचालित करने की अनुमति देने के लिए उत्तरदायी की शृंखला का उपयोग किया जा सकता है। विंडोज़ प्लेटफ़ॉर्म पर, माइक्रोसॉफ्ट-विशिष्ट अपवाद हैंडलिंग तंत्र या संरचित अपवाद हैंडलिंग या संरचित अपवाद हैंडलिंग (एसईएच) को एसईएच प्रयास/पकड़ ब्लॉक में मूल कोड को लपेटने के लिए नियोजित किया जा सकता है जिससे मशीन (सीपीयू/एफपीयू) उत्पन्न सॉफ़्टवेयर इंटरप्ट (जैसे) को कैप्चर किया जा सके व्यर्थ पॉइंटर एक्सेस उल्लंघन और डिवाइड-बाय-ज़ीरो ऑपरेशंस), और जेवीएम (अर्थात जावा साइड कोड) में बाधा उत्पन्न होने से पहले इन स्थितियों को संभालने के लिए, सभी संभावनाओं में जिसके परिणामस्वरूप अनचाहे अपवाद हो सकता है।
न्यूस्ट्रिंगयूटीएफ, गेटस्ट्रिंग यूटीएफलेंथ, गेटस्ट्रिंग यूटीएफचार्स,रिलीजस्ट्रिंग यूटीएफचर्स और गेटस्ट्रिंगयूटीएफक्षेत्र फ़ंक्शंस के लिए उपयोग की जाने वाली एन्कोडिंग को यूटीएफ-8 संशोधित किया गया है।[5] जो सभी इनपुट के लिए मान्य यूटीएफ-8 नहीं है, किन्तु वास्तव में अलग एन्कोडिंग है। शून्य वर्ण (U+0000) और कोडप्वाइंट जो प्लेन (यूनिकोड) या बेसिक मल्टीलिंगुअल प्लेन पर नहीं हैं (U+10000 से अधिक या उसके बराबर, अर्थात जिन्हें यूटीएफ-16 में सरोगेट जोड़े के रूप में दर्शाया गया है) को संशोधित यूटीएफ-8 में अलग-अलग विधि से एन्कोड किया गया है। कई प्रोग्राम वास्तव में इन फ़ंक्शंस का गलत विधि से उपयोग करते हैं और संशोधित यूटीएफ -8 स्ट्रिंग्स के अतिरिक्त मानक यूटीएफ -8 स्ट्रिंग्स के रूप में लौटाए गए या फ़ंक्शन में पास किए गए यूटीएफ -8 स्ट्रिंग्स का इलाज करते हैं। प्रोग्राम को न्यूस्ट्रिंग, गेटस्ट्रिंगलेंथ, गेटस्ट्रिंगचार्स, रिलीजस्ट्रिंगचार्स, गेटस्ट्रिंगरीजन, गेटस्ट्रिंगक्रिटिकल और रिलीजस्ट्रिंगक्रिटिकल फ़ंक्शंस का उपयोग करना चाहिए, जो छोटे-एंडियन आर्किटेक्चर पर यूटीएफ-16एल.ई एन्कोडिंग और बड़े-एंडियन आर्किटेक्चर पर यूटीएफ-16बीई का उपयोग करते हैं, और फिर यूटीएफ-16 से यूटीएफ- का उपयोग करते हैं।
मानचित्रण प्रकार
निम्न तालिका जावा (जेएनआई) और मूल कोड के बीच प्रकारों की मैपिंग दिखाती है।
सी टाइप | जावा भाषा प्रकार | विवरण | हस्ताक्षर टाइप करें |
---|---|---|---|
अचिन्हित वर्ण
यूइंट8_t |
जबूलियन | अहस्ताक्षरित 8 बिट्स | Z |
हस्ताक्षरित चार
int8_t |
जेबाइट | अहस्ताक्षरित 8 बिट्स | B |
अहस्ताक्षरित लघु
uint16_t |
जचर | unsigned 16 बिट्स | C |
छोटा
int16_t |
जेशॉर्ट | अहस्ताक्षरित 16 बिट्स | S |
पूर्णांक
int32_टी |
जिन्ट | अहस्ताक्षरित 32 बिट्स | I |
लम्बा लम्बा int64_टी |
ज्लॉन्ग | अहस्ताक्षरित 64 बिट्स | J |
फ्लोट | जेफ़्लोट | 32 बिट्स | F |
डबल | जेडबल | 64 बिट्स | D |
रिक्त | V |
इसके अतिरिक्त, हस्ताक्षर "L fully-qualified-class ;"
इसका कारण उस नाम से विशिष्ट रूप से निर्दिष्ट वर्ग होता है; उदाहरण के लिए, हस्ताक्षर "Ljava/lang/String;"
वर्ग को संदर्भित करता है java.lang.String
. इसके अतिरिक्त, उपसर्ग हस्ताक्षर करने के लिए उस प्रकार की सरणी बनाता है; उदाहरण के लिए, [I
कारण int सारणी प्रकार अंततः, ए void
हस्ताक्षर का उपयोग करता है
ये प्रकार विनिमेय हैं। कोई भी प्रयोग कर सकता है jint
जहां आप सामान्यतः का उपयोग करते हैं int
, और इसके विपरीत, बिना किसी प्रकार के रूपांतरण की आवश्यकता के। चूँकि, जावा स्ट्रिंग्स और एरे के बीच देशी स्ट्रिंग्स और एरे के बीच मैपिंग अलग है। यदि jstring
इसका प्रयोग वहां किया जाता है जहां a char *
होता है, कोड जेवीएम को क्रैश कर सकता है।
प्रदर्शन
कुछ परिस्थितियों में जेएनआई को अधिक ओवरहेड और प्रदर्शन हानि उठानी पड़ती है: [6]
- जेएनआई विधियों के लिए फ़ंक्शन कॉल महंगे हैं, जब किसी विधि को बार-बार कॉल करना होता है।
- मूल विधियाँ जेवीएम द्वारा इनलाइन नहीं की जाती हैं, इस प्रकार न ही विधि जेआईटी संकलित हो सकती है, क्योंकि विधि पहले से ही संकलित है।
- मूल कोड तक पहुंच के लिए जावा ऐरे को कॉपी किया जा सकता है, और बाद में वापस कॉपी किया जा सकता है। निवेश सरणी के आकार में रैखिक हो सकती है।
- यदि विधि किसी ऑब्जेक्ट को पारित कर देती है, या कॉलबैक करने की आवश्यकता होती है, जिससे मूल विधि संभवतः जेवीएम पर अपनी कॉल कर रही होटी है। मूल कोड से जावा फ़ील्ड, विधियों और प्रकारों तक पहुंचने के लिए प्रतिबिंब (कंप्यूटर प्रोग्रामिंग) के समान कुछ की आवश्यकता होती है। हस्ताक्षर स्ट्रिंग्स में निर्दिष्ट किए जाते हैं और जेवीएम से पूछे जाते हैं। यह धीमा और त्रुटि-प्रवण दोनों है।
- जावा स्ट्रिंग्स ऑब्जेक्ट हैं, लंबाई हैं और एन्कोडेड हैं। किसी स्ट्रिंग तक पहुँचने या बनाने के लिए O(n) प्रतिलिपि की आवश्यकता हो सकती है।
विकल्प
माइक्रोसॉफ्ट के जावा वर्चुअल मशीन (विजुअल जे++) के प्रोपर्टी कार्यान्वयन में जावा से मूल कोड को कॉल करने के लिए समान तंत्र था, जिसे रॉ नेटिव इंटरफ़ेस (आरएनआई) कहा जाता था। इसके अतिरिक्त, इसमें वर्तमान मूल कोड को कॉल करने का सरल विधि थी जो स्वयं जावा से अवगत नहीं था, जैसे कि विंडोज़ एपीआई, जिसे जे/डायरेक्ट कहा जाता है। चूँकि, इस कार्यान्वयन के बारे में J++ या सन-माइक्रोसॉफ्ट मुकदमे के विरुद्ध विज़ुअल J++ का अब रखरखाव नहीं किया जाता है।
जेएनआई की तुलना में आरएनआई का उपयोग कम अनाड़ी था, क्योंकि जावा पर्यावरण सूचक के साथ किसी बहीखाता की आवश्यकता नहीं थी। इसके अतिरिक्त, सभी जावा ऑब्जेक्ट्स को सीधे एक्सेस किया जा सकता है। इसे सुविधाजनक बनाने के लिए, टूल का उपयोग किया गया जो जावा कक्षाओं से हेडर फ़ाइलें उत्पन्न करता था। इसी प्रकार, आवश्यक मध्यवर्ती देशी लाइब्रेरी और जेएनआई का उपयोग करने की तुलना में जे/डायरेक्ट का उपयोग करना सरल था।
जावा नेटिव एक्सेस (जेएनए) समुदाय-विकसित लाइब्रेरी है जो जावा प्रोग्रामर्स को जेएनआई का उपयोग किए बिना मूल साझा लाइब्रेरी तक सरल पहुंच प्रदान करती है। चूँकि, इसके लिए निर्भर जार लाइब्रेरी के पुनर्वितरण की आवश्यकता है। जेएनआई को कोड करना कठिन होने और जेएनए के धीमे होने के बीच समझौता है।[7] जेएनआई को कोर जावा में बनाया गया है।
यह भी देखें
- जीआईडब्ल्यूएस (सॉफ्टवेयर)
- ग्लूजेन
- प्लेटफ़ॉर्म मंगलाचरण सेवाएँ
- स्वाइग
संदर्भ
- ↑ "जावा नेटिव इंटरफ़ेस अवलोकन". The Java Native Interface Programmer's Guide and Specification. Retrieved 2018-12-27.
- ↑ "जावा से असेंबली लैंग्वेज प्रोग्राम को लागू करना". Java.net. 2006-10-19. Archived from the original on 2008-03-30. Retrieved 2007-10-06.
- ↑ "असेंबली लैंग्वेज प्रोग्राम से जावा एप्लिकेशन लॉन्च करें". Java.net. 2006-10-19. Archived from the original on 2007-10-11. Retrieved 2007-10-04.
- ↑ The Invocation API. Sun Microsystems. https://docs.oracle.com/en/java/javase/11/docs/specs/jni/invocation.html
- ↑ "JNI Types and Data Structures".
- ↑ "जावा — जेएनआई कॉल धीमी क्यों होती है? - स्टैक ओवरफ़्लो".
- ↑ Zakusylo, Alexander. "Github मूल JNA स्रोत भी है। जेएनए बनाम जेएनआई बेंचमार्क गति परीक्षण". Github. Github. Retrieved 30 March 2023.
ग्रन्थसूची
- Gordon, Rob (March 1998). Essential Jni: Java Native Interface (1st ed.). Prentice Hall. p. 498. ISBN 0-13-679895-0.
- Liang, Sheng (June 20, 1999). Java(TM) Native Interface: Programmer's Guide and Specification (1st ed.). Prentice Hall. p. 320. ISBN 0-201-32577-2.