2010-10-13 6 views
54

मुझे कुछ सी फ़ंक्शंस मिल गए हैं जिन्हें मैं जेएनआई के माध्यम से बुला रहा हूं जो एक संरचना के लिए सूचक लेता है, और कुछ अन्य फ़ंक्शंस जो एक ही प्रकार की संरचना में पॉइंटर आवंटित/मुक्त करते हैं ताकि यह निपटने में थोड़ा आसान हो मेरा रैपर हैरानी की बात है कि जेएनआई दस्तावेज सी संरचनाओं से निपटने के बारे में बहुत कम कहता है।जेएनआई में जावा कोड पर आगे और आगे सी structs कैसे पास करें?

typedef struct _MyStruct { 
    float member; 
} MyStruct; 

MyStruct* createNewMyStruct(); 
void processData(int *data, int numObjects, MyStruct *arguments); 

इसी JNI सी आवरण फ़ाइल है:

मेरे सी हेडर फाइल तो की तरह लग रहा

JNIEXPORT jobject JNICALL 
Java_com_myorg_MyJavaClass_createNewMyStruct(JNIEnv *env, jobject this) { 
    return createNewMyStruct(); 
} 

JNIEXPORT void JNICALL 
Java_com_myorg_MyJavaClass_processData(JNIEnv *env, jobject this, jintArray data, 
             jint numObjects, jobject arguments) { 
    int *actualData = (*env)->GetIntArrayElements(env, data, NULL); 
    processData(actualData, numObjects, arguments); 
    (*env)->ReleaseIntArrayElements(env, data, actualData, NULL); 
} 

... और अंत में, इसी जावा वर्ग:

public class MyJavaClass { 
    static { System.loadLibrary("MyJniLibrary"); } 

    private native MyStruct createNewMyStruct(); 
    private native void processData(int[] data, int numObjects, MyStruct arguments); 

    private class MyStruct { 
    float member; 
    } 

    public void test() { 
    MyStruct foo = createNewMyStruct(); 
    foo.member = 3.14159f; 
    int[] testData = new int[10]; 
    processData(testData, 10, foo); 
    } 
} 

दुर्भाग्यवश, यह कोड createNewMyStruct() पर क्लिक करने के बाद JVM को क्रैश करता है। मैं जेएनआई के लिए थोड़ा नया हूं और मुझे पता नहीं है कि समस्या क्या हो सकती है।

संपादित करें: मुझे ध्यान रखना चाहिए कि सी कोड बहुत वैनिला सी है, अच्छी तरह से परीक्षण किया गया है और एक काम कर रहे आईफोन प्रोजेक्ट से पोर्ट किया गया था। साथ ही, यह प्रोजेक्ट एंड्रॉइड एनडीके फ्रेमवर्क का उपयोग कर रहा है, जो आपको जेएनआई के भीतर से एंड्रॉइड प्रोजेक्ट से देशी सी कोड चलाने देता है। हालांकि, मुझे नहीं लगता कि यह कड़ाई से एक एनडीके मुद्दा है ... यह मेरे हिस्से पर जेएनआई सेटअप/प्रारंभिक त्रुटि की तरह लगता है।

+0

त्रुटि के बारे में कुछ और विशिष्ट? कोई त्रुटि संदेश? –

+0

नहीं, यह सिर्फ जेआरई को दुर्घटनाग्रस्त करता है। जेएनआई से निपटने के बारे में यह एक गड़बड़ी है ... –

+1

चेकजेएनआई सुविधा हेइज़नबग्स में आने से पहले सामान्य कोड त्रुटियों को खोजने के लिए जोड़ा गया था। यह एमुलेटर में डिफ़ॉल्ट रूप से सक्षम है। Http://android.git.kernel.org/?p=platform/dalvik.git;a=tree;f=docs;h=b0d3023109f548626cce1a9a586c95e82fb012ac;hb=HEAD पर jni-tips और एम्बेडेड-वीएम-कंट्रोल दस्तावेज़ देखें किसी डिवाइस पर इसे सक्षम करने की जानकारी। – fadden

उत्तर

35

आप सी struct के रूप में ही सदस्यों के साथ एक जावा वर्ग बनाने की जरूरत है, और विधियों के माध्यम से सी कोड में उन्हें 'map' env-> GetIntField, env-> SetIntField, env-> GetFloatField, env-> SetFloatField, और इसी तरह - संक्षेप में, मैन्युअल श्रम के बहुत सारे, उम्मीद है कि पहले से ही ऐसे प्रोग्राम मौजूद हैं जो इसे स्वचालित रूप से करते हैं: जेएनएरेटर (http://code.google.com/p/jnaerator) और एसडब्ल्यूआईजी (http://www.swig.org/)। दोनों के पास उनके पेशेवर और विपक्ष हैं, पसंद आपके ऊपर है।

+11

क्या आप इस तरह के एकीकरण के कुछ सरल कोड उदाहरण पेस्ट कर सकते हैं? – Centurion

+4

@Centurion मुझे पता है कि यूआरएल आम तौर पर फंसे हुए हैं, लेकिन यह एक टिप्पणी है और मुझे यह वेब पेज मिला है इस सामान को समझने में बहुत मददगार: http://www3.ntu.edu.sg/home/ehchua/programming/java/ JavaNativeInterface.html # zz-5.1 – James

8

यह क्रैश हो रहा है क्योंकि Java_com_myorg_MyJavaClass_createNewMyStruct को "जॉबजेक्ट" वापस करने के लिए घोषित किया गया है, लेकिन वास्तव में संरचना MyStruct को वापस कर रहा है। यदि आपने चेकजेएनआई सक्षम के साथ इसे चलाया है, तो वीएम जोर से शिकायत करेगा और निरस्त करेगा। आपकी प्रक्रियाडेटा() फ़ंक्शन भी "तर्क" में दिए गए कार्यों के बारे में काफी परेशान होने जा रहा है।

एक नौकरी एक प्रबंधित ढेर पर एक वस्तु है। घोषित क्षेत्रों के पहले या बाद में इसमें अतिरिक्त सामान हो सकते हैं, और फ़ील्ड को किसी भी विशेष क्रम में स्मृति में निर्धारित नहीं किया जाना चाहिए। तो आप जावा क्लास के शीर्ष पर एक सी स्ट्रक्चर मैप नहीं कर सकते हैं।

इससे निपटने का सबसे सरल तरीका पहले के जवाब में पहचाना गया था: जेएनआई कार्यों के साथ जॉबजेक्ट में हेरफेर करें। जावा से या न्यू ऑब्जेक्ट के साथ ऑब्जेक्ट आवंटित करें, उचित कॉल के साथ ऑब्जेक्ट फ़ील्ड प्राप्त करें/सेट करें।

यहां "धोखा" के कई तरीके हैं। उदाहरण के लिए, आप अपने जावा ऑब्जेक्ट में एक बाइट [] शामिल कर सकते हैं जिसमें आकार (स्ट्रक्चर माईस्ट्रक्चर) बाइट्स हैं और फिर पॉइंटर प्राप्त करने के लिए GetByteArrayElements का उपयोग करें। थोड़ा बदसूरत, खासकर यदि आप जावा पक्ष से फ़ील्ड तक पहुंचना चाहते हैं।

6

सी संरचना वैरिएबल का संग्रह है (कुछ फ़ंक्शन पॉइंटर हैं)। जावा में पास एक अच्छा विचार नहीं है। आम तौर पर, समस्या यह है कि पॉइंटर की तरह जावा में अधिक जटिल प्रकार कैसे पारित किया जाए।

जेएनआई पुस्तक में, मूल में पॉइंटर/संरचना को रखने और जावा में निर्यात हेरफेर रखने की सिफारिश की जाती है। आप कुछ उपयोगी लेख पढ़ सकते हैं। The JavaTM Native Interface Programmer's Guide and Specification, मैंने पढ़ा है। 9.5 Peer Classes के साथ सौदा करने का एक समाधान है।

+2

लिंक मर चुका है - ऐसा लगता है जैसे ओरेकल ने सामग्री को नीचे ले लिया। दर्पण वाले कुछ साइटें हैं, या आप archive.org का उपयोग कर सकते हैं: http://web.archive.org/web/20070101174413/http://java.sun.com/docs/books/jni/ – fadden

-1
  1. जावा और सी ++ दोनों पक्षों पर कक्षा बनाएं, केवल सदस्य चर डालें। सी ++ structs वास्तव में सिर्फ सार्वजनिक डेटा सदस्यों के साथ कक्षाएं हैं। यदि आप वास्तव में शुद्ध सी में हैं, तो अभी पढ़ना बंद करें।
  2. सदस्य चर के लिए स्वचालित रूप से सेटर्स और गेटर्स बनाने के लिए अपने आईडीई का उपयोग करें।
  3. जावा क्लास से सी हेडर फ़ाइल जेनरेट करने के लिए जावा का उपयोग करें।
  4. सेटर्स और गेटर्स जेनरेट की गई हेडर फ़ाइल से मेल खाने के लिए सी ++ पक्ष पर कुछ संपादन करें।
  5. जेएनआई कोड में डाल दें।

यह एक आदर्श समाधान नहीं है, लेकिन यह आपको थोड़ा समय बचा सकता है, और यह आपको कम से कम एक कंकाल प्रदान करेगा जिसे आप संपादित कर सकते हैं। यह कार्यक्षमता एक आईडीई में जोड़ा जा सकता है, लेकिन बड़ी मांग के बिना, शायद यह नहीं होगा। अधिकांश आईडीई मिश्रित भाषा परियोजनाओं का समर्थन भी नहीं करते हैं, अकेले उन्हें एक-दूसरे से बात करने दें।

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