2013-06-05 8 views
5

मैं जेएनआई एपीआई से परिचित होने की कोशिश कर रहा हूं लेकिन संकलन करने के लिए नमूना सी ++ प्रोग्राम नहीं प्राप्त कर सकता। मुझे लिनक्स में संकलन और चलाने के लिए एक ही नमूना मिला है (नीचे दिए गए लिंक में प्रश्न पोस्ट करने के बाद) लेकिन इसे विंडोज़ में संकलित नहीं किया जा सकता है; मैं mingw g ++ का उपयोग कर रहा हूँ। मैंने विंडोज़ पथों में सभी शामिल पथ बदल दिए हैं और jni.h संकलन समय पर स्थित है लेकिन jvm.dll नहीं है।'JNI_CreateJavaVM' विंडो के अनिर्धारित संदर्भ

g++ -g -I"C:\Program Files (x86)\Java\jdk1.7.0_21\include" -I"C:\Program Files (x86)\Java\jdk1.7.0_21\include\win32" -L"C:\Program Files (x86)\Java\jdk1.7.0_21\jre\bin\server" callJava.cpp -ljvm 

और ...

**same as above with the additional** : -L"C:\Program Files (x86)\Java\jdk1.7.0_21\lib" 

त्रुटि मैं मिलता है:

undefined reference to `[email protected]' 

undefined reference to `JNI_CreateJavaVM' linux

यहाँ आदेशों मैं कोशिश की है संकलित करने के लिए उपयोग कर रहा है

और सीपीपी संकलित किया जा रहा है:

#include <jni.h> 

int main(){ 

    //firstTest(); 
    JavaVM *jvm; 
    JNIEnv *env; 

    JavaVMInitArgs vm_args; 
    JavaVMOption options[1]; 
    options[0].optionString = "-Djava.class.path=C:/Users/Ron/Dropbox/jni/simple/ctojava/win"; 
    vm_args.version = JNI_VERSION_1_6; 
    vm_args.options = options; 
    vm_args.nOptions = 1; 
    vm_args.ignoreUnrecognized = JNI_FALSE; 

    int res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args); 

    jclass cls = env->FindClass("Hello"); 
    jmethodID mid = env->GetStaticMethodID(cls, "staticInt", "(I)I"); 
    env->CallStaticVoidMethod(cls, mid,10); 

    jvm->DestroyJavaVM(); 
} 

मैंने कई उदाहरण देखे हैं लेकिन अभी भी समाधान नहीं मिल रहा है। किसी भी मदद की सराहना की है!

अद्यतन:

mingw32/bin/ld.exe: cannot find -ljvm 

जैसा कि मैंने कहा, इस सटीक दृष्टिकोण: मैं यकीन है कि jvm.dll क्योंकि स्थित किया जा रहा है अगर मैं एल "path_to_jvm" को दूर तो मैं त्रुटि मिलती हूँ लिनक्स में काम करता है, मैं विंडोज़ के लिए और क्या याद कर रहा हूं?

+0

यह एमएसवीसी के साथ जी ++ से निर्मित पुस्तकालयों से जुड़ने में एक समस्या हो सकती है। इस इंटरऑपरेबिलिटी पोस्ट को देखें: http://www.mingw.org/wiki/MixingCompilers। क्या आपने इसके बजाय विजुअल स्टूडियो का उपयोग करने पर विचार किया है? – maba

+0

@ माबा- मैंने विजुअल स्टूडियो में भी कोशिश की है लेकिन मुझे एक ही परिणाम मिल गया है। क्या आप इस तथ्य के बारे में जानते हैं कि jvm.dll एमएसवीसी के साथ बनाया गया है? मुझे लगता है कि यह नहीं है, लेकिन यह सिर्फ एक अनुमान है। – RBI

+1

@ आरबीआई यह एमएसवीसी के साथ बनाया गया है। निर्यात तालिका में फ़ंक्शन नामों को उलझाने का तरीका एक उपहार है। – greatwolf

उत्तर

3

आपके द्वारा चलाए गए मुद्दे को संक्षेप में नाम सजावट समस्या के रूप में समझा जा सकता है। लिंकर को दिए गए नाम के साथ फ़ंक्शन नहीं मिल सका क्योंकि यह jvm.dll में अलग-अलग सजाया गया है। प्रारंभिक त्रुटि आप मिल गया पर

देख रहे हैं:

undefined reference to '[email protected]' 

यह दो बातें की ओर इशारा कर रहा है:

  1. अंत में @12 प्रत्यय इंगित करता है कि JNI_CreateJavaVM supposely stdcall सम्मेलन उपयोग करता है।
  2. _imp_ उपसर्ग यह इंगित करता है कि यह फ़ंक्शन एक आयात लाइब्रेरी से है जो बाहरी रूप से लोड किए गए डीएल पर रीडायरेक्ट करता है जिसमें यह फ़ंक्शन अपनी निर्यात तालिका में दिखाई देता है।

jni.h में समारोह प्रोटोटाइप:

__declspec(dllimport) jint __stdcall 
JNI_CreateJavaVM(JavaVM **, void **, void *); 

अब gnu लिंकर कि MinGW के साथ आता है .a, MSVC के Coff से प्रतीकों के साथ काम कर सकते हैं:

_JNI_IMPORT_OR_EXPORT_ 
jint JNICALL JNI_CreateJavaVM(JavaVM **, void **, void *); 

शायद पूर्व प्रसंस्करण के बाद इस तरह दिखता है प्रारूप .lib और .dll सीधे। आपके मूल आदेश में, यह केवल खोज पथ में jvm.dll पाया गया (-L ...) इसलिए इसे उपयोग करने का प्रयास किया गया।

समस्या यह है कि jvm.dll के निर्यात तालिका में JNI_CreateJavaVM समारोह संयुक्त राष्ट्र से सजाया है, इसलिए यह एक cdecl समारोह की तरह लग रहा है। यह नाम लिंकर की अपेक्षा से मेल नहीं खाता है ताकि आपको अपरिभाषित संदर्भ त्रुटि मिल सके।

जावा देव किट को देखने से, इसमें jdk1.7.0_21\lib\jvm.lib पर एक आयात लाइब्रेरी शामिल है जिसमें इस प्रतीक के लिए उचित नाम सजावट है। आपका संशोधित आदेश काम करता है क्योंकि खोज पथ पर -L jdk1.7.0_21\lib जोड़कर यह अब jvm.lib और jvm.dll के विरुद्ध लिंक कर रहा है।

+2

बहुत अच्छी तरह से समझाया गया, मेरे लिए यह स्पष्ट करने के लिए धन्यवाद। – RBI

+0

हैलो। मैं jvm.lib फ़ाइल से लिंक कर रहा हूं और यह अभी भी मुझे यह त्रुटि देता है। कोई उपाय? इस्तेमाल किया गया आदेश g ++ है "-एलसी: \\ प्रोग्राम फ़ाइलें \\ जावा \\ jdk1.8.0_112 \\ lib" -o voce_synth.exe संश्लेषण Test.o -ljvm – Renato

+0

@Renato '-ljvm' स्विच' lib * जोड़ता है 'आयात फ़ाइल के लिए उपसर्ग। '-ljvm' g ++ के साथ IOW' libjvm.a' के लिए दिखता है। '-l: jvm.lib' आज़माएं या फ़ाइल नाम को पूरी तरह से पथ के साथ पास करें जैसा कि '-l' के बिना है। – greatwolf

2

समझ गया! पोस्ट को पढ़ने के लिए नीचे दिए गए मैं संकलन और क्रम में संकलन आदेश में अतिरिक्त लिंक के साथ नमूना चलाने के लिए jvm.lib लिंक करने में सक्षम था के बाद:

-L"C:\Program Files (x86)\Java\jdk1.7.0_21\lib" 

लिंक: Linking JNI to visual studio 2008

मुझे कोई ग कर रहा हूँ/सी ++ विशेषज्ञ इसलिए यदि कोई यह बताना चाहता है कि लिनक्स में नहीं होने पर यह अतिरिक्त लिंक क्यों आवश्यक है तो मुझे आपके उत्तर को स्वीकार करने में खुशी होगी।

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