का उपयोग कर जावा पर लौटाना मेरे पास एक जेएनआई फ़ंक्शन है, जो सी ++ में लिखा गया है, जो एक बाइट सरणी इनपुट के रूप में लेता है, इसे सेगमेंट करता है, और जावा में बाइट एरे की एक सरणी देता है।सी ++ में एक बाइट [] [] बनाना और जेएनआई
जेएनआईएक्सपोर्ट जॉबजेक्टएरे जेएनआईसीएलएल जावा_क्लास_एम विधि (जेएनआईएनएनवी * एनवी, जॉबजेक्ट ओ, जेबीटेएरे डेटा टू सेगमेंट);
जावा पक्ष पर, यह उतना ही आसान कुछ के रूप में बताया गया है:
byte[] arg = getRandomByteArray();
Object[] retVal = x.method(arg);
अब, मैं JNI हिस्सा पाने के कर रहा हूँ थोड़ी सूझबूझ से काम किया जाना है। मैं ऑब्जेक्ट्स की एक सरणी बनाने का इरादा रखता हूं, जिनमें से प्रत्येक एक बाइट सरणी है। ऐसा इसलिए है क्योंकि जेएनआई केवल सीमित प्रकार के जावा प्रकारों को परिभाषित करता है। एक jbyteArray प्रकार है, और एक jobjectArray प्रकार है, लेकिन कोई jarrayOfByteArrays प्रकार नहीं है।
jobjectArray retVal = env->NewObjectArray(numSegs, env->FindClass("[Ljava/lang/Object;"), env->NewByteArray(1024));
मैं तो इस सरणी में भर अनुक्रमित पुनरावृति, की तरह कुछ कर रही:
jbyteArray tmp = (jbyteArray) env->GetObjectArrayElement(retVal, i);
env->SetByteArrayRegion(tmp, 0, size, (jbyte*) sourceBuffer);
env->SetObjectArrayElement(retVal, i, (jobject) tmp); // <--- Questionable line
तो मैं वस्तुओं के अपने सरणी बनाने के लिए, प्रत्येक वस्तु एक नया बाइट [1024] के रूप में प्रारंभ किया जा रहा
और अधिकांश भाग अधिकांश के लिए बहुत अच्छा काम करता है। हालांकि, अगर मैं प्रत्येक बाइट सरणी को चर की लंबाई के लिए चाहता था तो क्या होगा? यही है, मैं बाइट एरे की सरणी को "जंजीर" होना चाहता हूं। प्रारंभिक मान के रूप में मैं NewObjectArray() को अंतिम पैरामीटर के रूप में क्या पास करूं? मैंने jobjectArray निर्माण के समय प्रारंभिक मान को रोकने के लिए प्रारंभिक मान के रूप में 0 को पार करने का प्रयास किया है, और उसके बाद SetObjectArrayElement() को पास करने के लिए नई jbyteArray ऑब्जेक्ट्स आवंटित करने की कोशिश की है, लेकिन यह केवल जब मैं SetObjectArrayElement को कॉल करने का प्रयास करता हूं तो यह केवल ArrayStoreException को फेंक देगा। दरअसल, tmp ऑब्जेक्ट को एक नया jbyteArray भी निर्दिष्ट करना (GetObjectArrayElement() से एक के बजाय) SetObjectArrayElement() को कॉल करते समय उसी अपवाद को फेंक दिया जाता है। क्या कोई कारण है कि कोड की आखिरी पंक्ति एक मुद्दा होगा? क्या एक पैरामीटर के रूप में jbyteArray के साथ SetObjectArrayElement() को कॉल करना संभव नहीं है?
ऐसा लगता है कि आगे निरीक्षण पर, "संदिग्ध रेखा" कुछ भी नहीं कर रही है। जब मैं इसे टिप्पणी करता हूं, तो टीएमपी में किए गए कोई भी बदलाव retVal में दिखाई देते हैं। मैं समझता हूं कि ऐसा इसलिए है क्योंकि SetByteArrayRegion कॉल बाइट सरणी से निपट रहा है जो jobjectArray में "इन" है, और एक प्रति नहीं। यह मेरे लिए पर्याप्त होगा यदि सभी पंक्तियां (बल्कि, सभी एकल-आयामी बाइट सरणी) एक ही लंबाई थीं। लेकिन वे नहीं हैं। मैं इस ऑब्जेक्ट सरणी में पंक्तियों में से किसी एक को एक नया बाइट सरणी कैसे सौंपूं?
टीएल; डीआर: जेएनआई के साथ, मेरे पास जॉबटेअरेज़ का नौकरी है। मैं न्यूबेटएरे के साथ बनाई गई एक नई चीज़ के साथ jbyteArrays में से किसी एक को कैसे बदलूं? संकेत: env-> SetObjectArrayElement (retVal, i, (jobject) env-> NewByteArray (आकार)); // काम नहीं करता है।
धन्यवाद, लेकिन दुर्भाग्य से मैं यहां जेएनआई के साथ फंस गया हूं। –
@SzymonSmakolski बफर आवंटित करने के लिए जेएनआई कोड से NewDirectByteBuffer का उपयोग करें। – Eugene
मेरी [सीमित] समझ के आधार पर, NewDirectByteBuffer देशी पक्ष पर आवंटित स्मृति के साथ काम करता है। मैं JVM को जावा बाइट [] ऑब्जेक्ट्स का एक गुच्छा आवंटित करना चाहता हूं जिसे मैं किसी ऑब्जेक्ट में क्रैक कर सकता हूं []। आपके द्वारा सुझाए गए दृष्टिकोण में मुझे सी ++ के नए ऑपरेटर का उपयोग करके प्रत्येक बाइट एरे आवंटित करना होगा, न कि JVM। मैं जेवीएम को जावा पक्ष पर वास्तव में समाप्त होने वाले किसी भी डेटा के आवंटन को संभालने देना चाहता हूं। –