2011-06-07 11 views
5

मुझे कुछ जेएनआई फ़ंक्शंस मिल गए हैं जिन्हें एक ही सी ++ ऑब्जेक्ट पर काम करना है। मैं उस ऑब्जेक्ट को जावा ऑब्जेक्ट में सहेजना चाहता हूं जिसके माध्यम से जेएनआई फ़ंक्शन का आह्वान किया जाता है, लेकिन ऐसा लगता है कि जावा के पास बाद में पहुंचने के लिए पॉइंटर्स को स्टोर करने का कोई तरीका नहीं है।जावा पर वापसी C++ ऑब्जेक्ट

ठीक है मुझे लगता है कि मैं एक भयानक काम अपने आप को इसलिए यहाँ समझा कर रहा हूँ एक उदाहरण है:

void clear_numbers(JNIEnv *env, jobject me) { 
    me.myCppVector.clear(); 
} 

void set_number(JNIEnv *env, jobject me, jint index, jint num) { 
    me.myCppVector[index]=num; 
} 

jint get_number(JNIEnv *env, jobject me, jint index) { 
    returnme.myCppVector[index]; 
} 

मेरे समस्या एक jobject.myCppVector पैदा कर रही है, ताकि मैं अलग से इसका इस्तेमाल करने में सक्षम हो जाएगा फ़ंक्शन कॉल

मुझे आशा है कि कोई मेरी ramblings

+1

शायद एक पूर्णांक के लिए सूचक परिवर्तित (मैं सी ++ वर्ग CppClass नाम दिया), और फिर जावा वस्तु – ignis

+0

के एक क्षेत्र में पूर्णांक की दुकान है कि असुरक्षित नहीं माना जाता है? साथ ही, सभी प्लेटफार्मों पर आकार (शून्य *) के बराबर आकार (जिंट) है? – Afiefh

+0

मुझे किसी भी कारण से पता नहीं है जिसके लिए यह असुरक्षित होना चाहिए। हालांकि, विभिन्न प्लेटफॉर्म पर पॉइंटर्स के अलग-अलग आकार होते हैं, जबकि जावा आदिम प्रकार नहीं होते हैं, और निश्चित रूप से इसका मतलब है कि आपको जावा कोड में विभिन्न प्रकार के प्राइमेटिव्स को पॉइंटर्स को मैप करना होगा - 32 बिट के लिए int, 64 बिट के लिए लंबा इत्यादि। http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#85587 – ignis

उत्तर

4

समझता है मुझे लगता है कि इसके बारे में जाने का मानक तरीका जावा में एक लंबा उपयोग करने के लिए सूचक स्टोर करने के लिए है, कि जिस तरह से अपने जावा कोड दोनों 32bit और 64bit सिस्टम पर काम करेंगे। जाहिर है आपको प्रत्येक प्लेटफार्म के लिए एक अलग सी ++ .so/.dll संकलित करने की आवश्यकता है।

class JavaClass 
{ 
    private long native_ptr = 0; 
    private native long createNativeInstance(params); 
    private native String nativeMethod(params); 
    private native void destroyNativeInstance(long p_native_ptr); 
    public JavaClass(params) 
    { 
     this.native_ptr = createNativeInstance(params); 
    } 
    public String javaMethod(params) 
    { 
     nativeMethod(this.native_ptr, params); 
    } 
    public void finalize() 
    { 
     destroyNativeInstance(this.native_ptr); 
    } 
} 

और अपने सी ++ आवरण कोड इस तरह दिखता है:

तो एक विधि के साथ एक सी ++ वर्ग के लिए एक सरल जावा आवरण की तरह कुछ दिखेगा।

JNIEXPORT jlong JNICALL Java_JavaClass_createNativeInstance 
    (JNIEnv* p_jenv 
    , jobject p_jthis 
    , params) 
{ 
    // Convert params from Java types to C++ types if required 
    return (jlong) new CppClass(converted_params); 
} 

JNIEXPORT void JNICALL Java_JavaClass_destroyNativeInstance 
    (JNIEnv* p_jenv 
    , jobject p_jthis 
    , jlong  p_native_ptr) 
{ 
    if(p_native_ptr) 
     delete (CppClass*)p_native_ptr; 
} 

JNIEXPORT jstring JNICALL Java_JavaClass_nativeMethod 
    (JNIEnv* p_jenv 
    , jobject p_jthis 
    , jlong  p_native_ptr 
    , params 
    ) 
{ 
    // Convert params from Java types to C++ types if required 
    std::string cpp_result = ((CppClass*)p_native_ptr)->cppMethod(converted_params); 
    jstring java_result = p_jenv->NewStringUTF(cppResult.c_str()); 
    return java_result; 
    // NOTE: std::string destructor will free cpp_result memory 
} 
संबंधित मुद्दे