2013-08-07 12 views
5

का उपयोग कर जावा में एक सी ++ अमूर्त वर्ग उपclass मेरे पास एक सी ++ लाइब्रेरी है जिसे मुझे मौजूदा एंड्रॉइड कार्यान्वयन में उपयोग करना है। मैं एंड्रॉइड एनडीके का उपयोग कर रहा हूं और जेएनआई के माध्यम से सी ++ कक्षाओं का उपयोग कर रहा हूं।जेएनआई

हालांकि, मैं जेएनआई का उपयोग कर जावा में सी ++ अमूर्त वर्ग को उप-वर्ग कैसे प्राप्त करने में सक्षम नहीं हूं।

समस्याएं मुझे सामना करती हैं: मेरा उद्देश्य अमूर्त सी ++ वर्ग को उप-वर्गीकरण करके सी ++ में वर्चुअल विधियों के लिए जावा कार्यान्वयन प्रदान करना है। मैंने मूल पुस्तकालय लोड किया है और मैं मूल तरीकों की घोषणा करने की कोशिश कर रहा हूं। सी ++ विधियों में कीवर्ड 'आभासी' है। जब मैं सी ++ लाइब्रेरी को लोड करने के बाद जावा में देशी कार्यों की घोषणा करता हूं, तो 'वर्चुअल' पहचाना नहीं जाता है। यहाँ क्या गलत है?

किसी भी मदद की सराहना की जाती है। मैं जेएनआई के लिए नौसिखिया हूँ। अग्रिम में धन्यवाद।

+1

प्रारंभ [यहां] (http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/intro.html#wp725)। आप पाएंगे कि जेएनआई गोंद जावा को सी ++ कक्षाओं से बंधे नहीं है। इसके लिए, आपको जेएनआई के आसपास बनाया गया कुछ चाहिए।[जेस] (http://code.google.com/p/jace/wiki/Overview) उपयोगी है लेकिन जहां तक ​​आप वर्णन करते हैं उतना नहीं जाता है। मेरी शर्त यह है कि आपको कुछ भी नहीं मिलेगा जो आपको मैन्युअल रूप से एक ठोस सी ++ वर्ग बनाने और उसे लपेटने से बचाता है। –

+0

@ टॉमब्लोडेट: धन्यवाद! रैपर बनाने के लिए, क्या आप SWIG जैसे कुछ टूल का सुझाव देते हैं या ऐसा करने का कोई और तरीका है? – vvid

+0

भी [ब्रिजजे] (http://bridj.googlecode.com) पर एक नज़र डालें। –

उत्तर

5

के पर विचार हम एक सी ++ वर्ग करते हैं:

class iVehicle 
{ 
public: 
    virtual void Run() {}; // not-pure virtual here for simplicity of a wrapper, but could be pure (see the end of the post) 
    virtual int GetSize() const; // we want to reuse it in Java 
}; 

हम जावा में एक वर्ग Bot बनाना चाहते हैं कि इस अर्थ में कि super करने के लिए कॉल iVehicle::GetSize() से सी ++ कोड आह्वान और सी से, में वर्ग iVehicle फैली ++ दृष्टिकोण, हम Bot के उदाहरणों को iVehicle* चर के रूप में उपयोग कर सकते हैं। यह कठिन है क्योंकि सी ++ प्रतिबिंब के लिए कोई अच्छी अंतर्निहित कार्यक्षमता प्रदान नहीं करता है।

यहां एक संभावित समाधान है।

जावा में सी ++ वर्ग का उपयोग करने के लिए हम, एक जावा आवरण उत्पन्न करने के लिए की जरूरत है अर्थात्:

class iVehicle 
{ 
    public void Run() { Native_Run(); } 
    public int GetSize() { return Native_GetSize(); } 

    private native void Native_Run(); 
    private native int Native_GetSize(); 

    // typecasted to pointer in C++ 
    private int NativeObjectHolder; 

    // create C++ object 
    native static private int CreateNativeObject(); 
} 

जावा में उपयोग सरल है:

class Bot extends iVehicle 
{ 
    public int GetSize() 
    { 
     if (condition) return 0; 

     // call C++ code 
     return super.GetSize(); 
    } 
} 

हालांकि, वहाँ एक सी ++ हिस्सा है यह कोड:

static jfieldID gNativeObjectHolderFieldID; 

JNIEXPORT void JNICALL Java_com_test_iVehicle_Run(JNIEnv* env, jobject thiz) 
{ 
    int Value = env->GetIntField(thiz, gNativeObjectHolderFieldID); 
    iVehicle* Obj = (iVehicle*)Obj; 

    // todo: add checks here, for NULL and for dynamic casting 

    Obj->Run(); 
} 

इसी तरह का कोड GetSize() के लिए है।

फिर जावा के Bot का एक उदाहरण बनाना आपको CreateNativeObject() पर कॉल करना होगा और लौटा मान NativeObjectHolder फ़ील्ड पर असाइन करना होगा।

JNIEXPORT int JNICALL Java_com_test_iVehicle_CreateNativeObject(JNIEnv* env, jobject thiz) 
{ 
    iVehicle* Obj = new iVehicle; 
    return (int)Obj;  
} 

तो, यह योजना है। इस काम को करने के लिए आपको विनाश कोड जोड़ने और इस गोंद कोड को उत्पन्न करने के लिए सी ++ कक्षाओं को पार्स करने की आवश्यकता होगी।

जोड़ा गया:

मामले में जहां iVehicle वास्तव में सार आप एक गैर सार आवरण है कि आप का दृष्टांत करने में सक्षम हैं उत्पन्न करने के लिए होगा:

class iVehicle 
{ 
    virtual void Run() = 0; 
} 

class iVehicle_Wrapper: public iVehicle 
{ 
    virtual void Run() { ERROR("Abstract method called"); }; 
} 

और CreateNativeObject() में iVehicle_Wrapper का दृष्टांत। Vuala! आपने जावा में एक सार सी ++ कक्षा विरासत में ली है।

+0

विस्तृत उत्तर के लिए धन्यवाद। लेकिन, अगर मैं सी ++ वर्ग के अमूर्त तरीकों के लिए जावा कार्यान्वयन प्रदान करना चाहता हूं और फिर इस जावा सबक्लास को सी ++ में फिर से उपयोग करना चाहता हूं तो क्या होगा? – vvid

+0

सी ++ में जावा उप-वर्गों का उपयोग इस कहानी के लिए एक अनुक्रम है। आपको एक रैपर ''iVehicle_Wrapper'' उत्पन्न करने की आवश्यकता है जो जावा की ऑब्जेक्ट/विधि की आईडी रखेगी और इसे कॉल करने के लिए जेएनआई का उपयोग करेगी। –

+0

मेरा सुझाव है कि आप * सहकर्मी वर्ग * की जांच करें। आप 'IVehicle' के लिए जावा प्रॉक्सी क्लास करेंगे - जो सी ++ विधियों को प्रतिबिंबित करने वाली चीज़ों के जावा पक्ष पर एक अमूर्त वर्ग है। सी ++ अंत में, आप 'iVehicle' का एक ठोस कार्यान्वयन चाहते हैं जो सभी अमूर्त आभासी कार्यों को लागू करता है, जो उन्हें जावा प्रॉक्सी में जेएनआई के साथ अग्रेषित करता है। – marko