जेएनआई की तुलना में जेएनए को देशी कोड का उपयोग करना आसान लगता है। आप किन मामलों में JNI का उपयोग JNA पर करेंगे?
जेएनआई की तुलना में जेएनए को देशी कोड का उपयोग करना आसान लगता है। आप किन मामलों में JNI का उपयोग JNA पर करेंगे?
जवाबों:
ये समस्याएं हैं जिनका मैंने सामना किया है। शायद ज्यादा है। लेकिन सामान्य प्रदर्शन में, jna और jni के बीच भिन्न नहीं है, इसलिए जहाँ भी आप JNA का उपयोग कर सकते हैं, उसका उपयोग करें।
संपादित करें
यह उत्तर काफी लोकप्रिय प्रतीत होता है। तो यहाँ कुछ जोड़ हैं:
इसलिए, मेरा अब भी मानना है कि जहाँ भी संभव हो, JNA या ब्रिजेज का उपयोग करना बेहतर है, और यदि प्रदर्शन महत्वपूर्ण है, तो jni में वापस लौटें, क्योंकि यदि आपको अक्सर मूल कार्यों को कॉल करने की आवश्यकता होती है, तो प्रदर्शन हिट ध्यान देने योग्य है।
JNIEXPORT
कार्यों को बुला सकता है। मैं वर्तमान में एक विकल्प के रूप में JavaCpp की खोज कर रहा हूं, जो जेएनआई का उपयोग करता है, लेकिन मुझे नहीं लगता कि वेनिला जेएनआई इसका समर्थन करता है। क्या वेनिला जेएनआई का उपयोग करके सी ++ सदस्य कार्यों को कॉल करने का एक तरीका है जिसे मैं देख रहा हूं?
इस तरह के एक सामान्य सवाल का जवाब देना मुश्किल है। मुझे लगता है कि सबसे स्पष्ट अंतर यह है कि जेएनआई के साथ, प्रकार रूपांतरण जावा / देशी सीमा के मूल पक्ष पर लागू किया जाता है, जबकि जेएनए के साथ, प्रकार रूपांतरण जावा में लागू किया जाता है। यदि आप पहले से ही सी में प्रोग्रामिंग के साथ काफी सहज महसूस करते हैं और खुद को कुछ मूल कोड लागू करना है, तो मुझे लगता है कि जेएनआई बहुत जटिल नहीं लगेगा। यदि आप एक जावा प्रोग्रामर हैं और केवल JNI के साथ इतनी स्पष्ट समस्याओं से बचने के लिए JNA का उपयोग करना संभव नहीं है, तो JNA का उपयोग करके किसी तीसरे पक्ष के मूल पुस्तकालय को आमंत्रित करना आवश्यक है।
हालाँकि, मैंने कभी भी किसी भी तरह के मतभेद नहीं किए हैं, मैं डिजाइन के कारण, कम से कम यह मानता हूं कि कुछ स्थितियों में JNA के साथ उस प्रकार का रूपांतरण JNI के साथ और भी बुरा प्रदर्शन करेगा। उदाहरण के लिए, जब सरणियाँ गुजरती हैं, तो JNA प्रत्येक फ़ंक्शन कॉल की शुरुआत में जावा से मूल में और फ़ंक्शन कॉल के अंत में वापस बदल जाएगा। जेएनआई के साथ, आप अपने आप को नियंत्रित कर सकते हैं जब सरणी का एक मूल "दृश्य" उत्पन्न होता है, संभवतः केवल सरणी के एक हिस्से का एक दृश्य बना रहा है, कई फ़ंक्शन कॉल पर दृश्य रखें और अंत में दृश्य को छोड़ दें और यदि आप चाहें तो तय करें परिवर्तनों को रखने के लिए (संभवतः डेटा वापस कॉपी करने के लिए आवश्यक है) या परिवर्तनों को त्यागें (कोई प्रतिलिपि आवश्यक नहीं)। मुझे पता है कि आप मेमोरी क्लास में JNA के साथ फंक्शन कॉल में एक देशी सरणी का उपयोग कर सकते हैं, लेकिन इसके लिए मेमोरी कॉपी करने की भी आवश्यकता होगी, जेएनआई के साथ अनावश्यक हो सकता है। अंतर प्रासंगिक नहीं हो सकता है, लेकिन यदि आपका मूल लक्ष्य मूल कोड में इसके कुछ हिस्सों को लागू करके अनुप्रयोग प्रदर्शन को बढ़ाना है, तो एक खराब प्रदर्शन पुल तकनीक का उपयोग करना सबसे स्पष्ट विकल्प नहीं लगता है।
यह केवल वही है जो मैं अपने सिर के ऊपर से आ सकता हूं, हालांकि मैं किसी भी तरह का भारी उपयोगकर्ता नहीं हूं। यह भी लगता है कि आप JNA से बच सकते हैं यदि आप एक बेहतर इंटरफ़ेस चाहते हैं जो वे प्रदान करते हैं लेकिन आप जावा में उसके आसपास कोड कर सकते हैं।
वैसे, हमारी एक परियोजना में, हमने एक बहुत छोटा जेएनआई फुट प्रिंट रखा। हमने अपने डोमेन ऑब्जेक्ट्स का प्रतिनिधित्व करने के लिए प्रोटोकॉल बफ़र्स का उपयोग किया और इस प्रकार जावा और सी को ब्रिज करने के लिए केवल एक ही देशी फ़ंक्शन था (फिर निश्चित रूप से सी फ़ंक्शन अन्य फ़ंक्शन का एक गुच्छा कहलाएगा)।
यह एक सीधा जवाब नहीं है और मुझे JNA के साथ कोई अनुभव नहीं है, लेकिन जब मैं JNA का उपयोग करने वाली परियोजनाओं को देखता हूं और SVNKit, IntelliJ IDEA, NetBeans IDE, आदि जैसे नाम देखता हूं, तो मुझे विश्वास है कि यह एक बहुत अच्छा पुस्तकालय है।
वास्तव में, मुझे निश्चित रूप से लगता है कि मैंने जेएनआई के बजाय जेएनए का उपयोग किया होगा जब मुझे वास्तव में जेएनआई (जो उबाऊ विकास प्रक्रिया है) की तुलना में सरल दिखता है। बहुत बुरा, JNA को इस समय जारी नहीं किया गया था।
यदि आप जेएनआई प्रदर्शन चाहते हैं, लेकिन इसकी जटिलता से भयभीत हैं, तो आप उन उपकरणों का उपयोग करने पर विचार कर सकते हैं जो जेएनआई बाइंडिंग स्वचालित रूप से उत्पन्न करते हैं। उदाहरण के लिए, JANET (अस्वीकरण: मैंने इसे लिखा था) आपको जावा और C ++ कोड को एक ही स्रोत फ़ाइल में मिलाने की अनुमति देता है, और जैसे मानक जावा सिंटैक्स का उपयोग करके C ++ से जावा तक कॉल करता है। उदाहरण के लिए, यहां बताया गया है कि आप जावा मानक आउटपुट में C स्ट्रिंग कैसे प्रिंट करेंगे:
native "C++" void printHello() {
const char* helloWorld = "Hello, World!";
`System.out.println(#$(helloWorld));`
}
JANET तब बैकलिक-एम्बेडेड जावा को उपयुक्त JNI कॉल में अनुवादित करता है।
मैंने वास्तव में जेएनआई और जेएनए के साथ कुछ सरल बेंचमार्क किए।
जैसा कि दूसरों ने पहले ही बताया है, जेएनए सुविधा के लिए है। JNA का उपयोग करते समय आपको मूल कोड संकलित करने या लिखने की आवश्यकता नहीं है। जेएनए का मूल पुस्तकालय लोडर भी मैंने कभी देखा है उपयोग करने के लिए सबसे अच्छा / आसान में से एक है। अफसोस की बात है, आप इसे जेएनआई के लिए उपयोग नहीं कर सकते हैं ऐसा लगता है। (यही कारण है कि मैंने System.loadLibrary () के लिए एक विकल्प लिखा है जो JNA के पथ सम्मेलन का उपयोग करता है और क्लासपैथ (यानी जार) से निर्बाध लोडिंग का समर्थन करता है।
हालांकि, JNA का प्रदर्शन JNI की तुलना में बहुत खराब हो सकता है। मैंने एक बहुत ही सरल परीक्षण किया, जिसे एक साधारण देशी पूर्णांक वृद्धि फ़ंक्शन "रिटर्न आर्ग + 1" कहा जाता है। जेएमएच के साथ किए गए बेंचमार्क ने दिखाया कि जेएनआई उस फ़ंक्शन को जेएनए से 15 गुना तेज है।
एक अधिक "जटिल" उदाहरण जहां मूल फ़ंक्शन 4 मानों के पूर्णांक सरणी को प्रस्तुत करता है फिर भी पता चलता है कि जेएनआई का प्रदर्शन जेएनए से 3 गुना तेज है। कम लाभ संभवत: इस वजह से था कि आप जेएनआई में सरणियों का उपयोग कैसे करते हैं: मेरे उदाहरण ने कुछ सामान बनाया और प्रत्येक संक्षिप्त ऑपरेशन के दौरान इसे फिर से जारी किया।
कोड और परीक्षण के परिणाम जीथब में पाए जा सकते हैं ।
मैंने प्रदर्शन तुलना के लिए जेएनआई और जेएनए की जांच की क्योंकि हमें उनमें से एक को परियोजना में एक डीएलएल को बुलाने का फैसला करने की जरूरत थी और हमारे पास वास्तविक समय की कमी थी। परिणामों से पता चला है कि JNI का JNA (लगभग 40 गुना) की तुलना में अधिक प्रदर्शन है। हो सकता है कि JNA में बेहतर प्रदर्शन के लिए कोई ट्रिक हो लेकिन यह एक साधारण उदाहरण के लिए बहुत धीमी है।
जब तक मुझे कुछ याद नहीं आ रहा है, तब तक JNA बनाम JNI के बीच मुख्य अंतर नहीं है कि JNA के साथ आप मूल (C) कोड से जावा कोड को कॉल नहीं कर सकते?
मेरे विशिष्ट अनुप्रयोग में, जेएनआई उपयोग करने के लिए बहुत आसान साबित हुआ। मुझे धारावाहिक बंदरगाह से और उसके लिए और लगातार धाराएँ पढ़ने और लिखने की ज़रूरत थी - और कुछ नहीं। जेएनए में बहुत ही शामिल बुनियादी ढांचे को सीखने की कोशिश करने के बजाय, मैंने विंडोज में मूल इंटरफ़ेस को एक विशेष उद्देश्य वाले डीएलएल के साथ प्रोटोटाइप करना बहुत आसान पाया, जो सिर्फ छह कार्यों का निर्यात करता है: