2011-08-13 13 views
8

पर सेल्सियस के लिए JNI के माध्यम से मैं जावा में एक byte[] जो 256 बाइट्स जो मैं सीसमस्या गुजर बाइट [] एंड्रॉयड

में एक देशी कार्य करने के लिए पारित जब मैं से बाहर डेटा प्राप्त करने की कोशिश के रूप में अपनी लंबाई की रिपोर्ट है इस सरणी यह ​​पूरी तरह से गलत था और जब मैं इसे बाहर मुद्रित यह डेटा मैं बाहर मुद्रित सही इससे पहले कि मैं यह सी

के लिए पारित

मैं दोनों GetByteArrayRegion और GetByteArrayElements लेकिन कुछ नहीं लगता सहित डेटा का उपयोग करने के लिए कुछ तरीके की कोशिश की से मेल नहीं खाती मुझे वह डेटा देने के लिए जो मुझे उम्मीद है।

जैसा कि मैंने जांच कर रहा था कि मैं क्या इस JNI jbyteArray की लंबाई का मानना ​​था पर देखने की कोशिश की GetArrayLength के साथ था - यह १०७९१४२९६० के रूप में लंबाई, अब तक 256 बाइट्स मैं अपेक्षा से अधिक की सूचना दी। इसके अलावा मूल्य अलग अलग हर बार समारोह बुलाया गया था था, उदाहरण के लिए एक और समय GetArrayLength लौटे 1079145720.

यहाँ कोड मैं सरणी तक पहुँचने के लिए उपयोग कर रहा हूँ है:

JNIEXPORT jbyteArray function(JNIEnv* env, jbyteArray array) { 
    int length = (*env)->GetArrayLength(env, array); 

    jbyte data[256]; 

    (*env)->GetByteArrayRegion(env, array, 0, 256, data); 
    //also tried 
    //jbyte *data = (jbyte*) (*env)->GetByteArrayElements(env, array, NULL); 
} 

यह सुंदर सीधे आगे लगता है तो मैं मुझे यकीन नहीं है कि क्या हो रहा है। सरणी जावा से ठीक प्रतीत होती है लेकिन इसे सी में उत्पन्न किया गया था और मुझे वापस भेज दिया गया था, इसलिए मुझे लगता है कि कुछ गलत हो सकता है, जहां जावा परवाह नहीं है, लेकिन जब यह वापस आता है तो सरणी तोड़ता है।

यहां कोड है मैं सरणी उत्पन्न करता था और इसे जावा पर वापस भेजता था:

//there is some openSSL stuff here that sets up a pointer to an RSA struct called keys that is size bytes large 

jbyteArray result = (*env)->NewByteArray(env, size); 

(*env)->SetByteArrayRegion(env, result, 0, size, (jbyte*)keys; 

क्या मुझे कुछ याद आ रहा है?

धन्यवाद

+0

जावा कोड कैसा दिखता है? –

+0

जावा में कुछ भी दिलचस्प नहीं होता है मैं साझा किए गए ऑब्जेक्ट ऑब्जेक्ट से बाइट सरणी लेता हूं और फिर डेटा और लम्बाई की जांच करता हूं जो दोनों ठीक दिखते हैं और फिर इसे देशी फ़ंक्शन –

उत्तर

12

इस समारोह प्रोटोटाइप गलत है:

JNIEXPORT jbyteArray function(JNIEnv* env, jbyteArray array) 

दूसरा तर्क या तो एक jclass या एक jobject है। यदि आपका विधि स्थिर है, यह होना चाहिए:

JNIEXPORT jbyteArray function(JNIEnv* env, jclass cls, jbyteArray array) 

और यह स्थिर नहीं रहती है, तो:

JNIEXPORT jbyteArray function(JNIEnv* env, jobject obj, jbyteArray array) 

आप एक सरणी है, जो अप्रत्याशित परिणाम है कि आप प्राप्त बताते हैं के रूप में वर्ग या वस्तु के इलाज कर रहे हैं।

+0

यह समस्या थी। यह थोड़ी देर के बाद से मैंने जेएनआई में कोई काम किया था और जब मैं प्रोटोटाइप स्थापित कर रहा था तो मैं भूल गया था कि आपको यह करना है। धन्यवाद –

0

स्ट्रिंग को '\ 0' वर्ण के साथ जोड़ने का प्रयास करें। शायद यह स्ट्रिंग के अंत की पहचान करने में सक्षम नहीं है।

+0

पर पास करते हैं, इसकी स्ट्रिंग नहीं है इसकी संरचना –

1

मुझे लगता है कि मुख्य समस्या यह है कि आप एक ओपनएसएसएल संरचना को बाइट सरणी में मजबूर करते हैं। अधिकतर संभावना है कि यह संरचना समय के साथ मुक्त हो जाएगी। इससे आपको वापस आने पर अजीब और अलग-अलग लंबाई की सूचना दी जाएगी। जब आप वापस लौटते हैं तो RSA* जावा में भी आपकी मदद नहीं करेगा - जावा को उस विशेष संरचना के बारे में कोई जानकारी नहीं है और डी इसे पहचानने में सक्षम नहीं होगा ।

क्या आप में से एक का उपयोग कर रहा प्रयास करना चाहिए

  • i2d_PKCS8PrivateKey_bio (जैव * रक्तचाप, EVP_PKEY * x, स्थिरांक EVP_CIPHER * ENC, चार * kstr, पूर्णांक Klen, pem_password_cb * सीबी, शून्य * यू)
  • पूर्णांक i2d_RSA_PUBKEY (आरएसए * एक, अहस्ताक्षरित चार ** पीपी)

तुम सिर्फ सार्वजनिक कुंजी जानकारी या भी जावा के लिए निजी जानकारी (see also here) पास करना चाहते हैं, इस पर निर्भर करता है। इस तरह से आप शुरुआत से ही बाइट सरणी से निपटने के लिए सुनिश्चित हो सकते हैं।

एक बार यह आपके लिए काम करता है (तकनीक जो आपने पहले से कोशिश की है) का उपयोग करके, जावा में वापस आप बाइट सरणी को सार्थक में पार्स कर सकते हैं। यह सार्वजनिक कुंजी मामले में सीधे आगे है: X509EncodedKeySpec का उपयोग अपनी सरणी के साथ करें और KeyFactory#generatePublic का उपयोग करके सार्वजनिक कुंजी उत्पन्न करें।

निजी कुंजी मामले में चीजें थोड़ा अधिक जटिल हैं।जावा केवल PKCS#8 format को समझता है जबकि ओपनएसएसएल डिफ़ॉल्ट रूप से पीकेसीएस # 1 प्रारूप के अनुसार अपनी निजी आरएसए कुंजी को एन्कोड करता है। लेकिन आप i2d_PKCS8PrivateKey_bio का उपयोग कर अपनी कुंजी को पहले ही पीकेसीएस # 8 में बदल सकते हैं। आप रैप करने के लिए की जरूरत है अपने RSA* एक EVP_PKEY* पहले, हालांकि के रूप में:

EVP_pkey *pkey = EVP_PKEY_new(); 
EVP_PKEY_assign_RSA(pkey, rsa); 

अपने कुंजी एन्क्रिप्ट और एक in-memory BIO का उपयोग न करें, तो जावा के लिए खत्म हो और वहाँ PKCS8EncodedKeySpec के निर्माता के परिणामस्वरूप बाइट सरणी गुजरती हैं और अंत में उत्पन्न अपने KeyFactory के साथ निजी कुंजी।

संबंधित मुद्दे