2009-06-14 9 views

उत्तर

34

हाँ आप कर सकते हैं, लेकिन यह थोड़ा संकलित है, और एक प्रतिबिंबित/गैर प्रकार के सुरक्षित तरीके से काम करता है (उदाहरण सी ++ एपीआई का उपयोग करता है जो सी संस्करण की तुलना में थोड़ा क्लीनर है)। इस मामले में यह सी कोड के भीतर से जावा वीएम का एक उदाहरण बनाता है।

g++ -I/usr/lib/jvm/java-6-sun/include \ 
    -I/usr/lib/jvm/java-6-sun/include/linux \ 
    -L/usr/lib/jvm/java-6-sun/jre/lib/i386/server/ -ljvm jnitest.cc 

नोट:: अपनी मूल बुलाया पहले जावा से बुलाया जा रहा है तो एक वीएम उदाहरण

#include<jni.h> 
#include<stdio.h> 

int main(int argc, char** argv) { 

    JavaVM *vm; 
    JNIEnv *env; 
    JavaVMInitArgs vm_args; 
    vm_args.version = JNI_VERSION_1_2; 
    vm_args.nOptions = 0; 
    vm_args.ignoreUnrecognized = 1; 

    // Construct a VM 
    jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); 

    // Construct a String 
    jstring jstr = env->NewStringUTF("Hello World"); 

    // First get the class that contains the method you need to call 
    jclass clazz = env->FindClass("java/lang/String"); 

    // Get the method that you want to call 
    jmethodID to_lower = env->GetMethodID(clazz, "toLowerCase", 
             "()Ljava/lang/String;"); 
    // Call the method on the object 
    jobject result = env->CallObjectMethod(jstr, to_lower); 

    // Get a C-style string 
    const char* str = env->GetStringUTFChars((jstring) result, NULL); 

    printf("%s\n", str); 

    // Clean up 
    env->ReleaseStringUTFChars(jstr, str); 

    // Shutdown the VM. 
    vm->DestroyJavaVM(); 
} 

(Ubuntu पर) संकलन करने के लिए निर्माण करने के लिए कोई जरूरत नहीं है अगर वह में से प्रत्येक से वापसी कोड सही त्रुटि प्रबंधन को लागू करने के लिए इन तरीकों की जांच की जानी चाहिए (मैंने सुविधा के लिए इसे अनदेखा कर दिया है)। जैसे

str = env->GetStringUTFChars(jstr, NULL); 
if (str == NULL) { 
    return; /* out of memory */ 
} 
+1

+1। क्या हेडर, फ़ंक्शन हस्ताक्षर आदि स्थापित करने के लिंक/उदाहरण भी शामिल करना चाहते हैं? – poundifdef

+0

आपका समाधान बहुत अच्छा है, लेकिन हमने जो वर्गपैथ बनाया है उसे सेट या सेट करना है उदाहरण के लिए HelloWorld.java i.e 'env-> FindClass (" HelloWorld ");' –

9

हाँ, यह है, लेकिन आप JNI के माध्यम से यह करना है: http://java.sun.com/javase/6/docs/technotes/guides/jni/index.html

+0

मैंने देखा है कि जेएनआई जावा से सी ++ को कॉल करता था। यह नहीं पता था कि यह दूसरी तरफ भी काम करता है। – Kieveli

+3

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

3

ऐसे कई तरीके हैं। Here कुछ विचार हैं। इसके अतिरिक्त, वाणिज्यिक जावा-कॉम पुल सी ++ से जावा तक COM संचार की अनुमति देते हैं (यदि आप विंडोज का उपयोग कर रहे हैं)। आपको CNI पर भी देखना चाहिए।

2

हाँ, आप सी से एक जावा समारोह ++ या सी कॉल कर सकते हैं, लेकिन जब तक आप कॉम या CORBA की तरह कुछ (या किसी अन्य 3-पक्ष टूल में मैं शायद के बारे में पता नहीं कर रहा हूँ) का उपयोग कर रहे आप करेंगे जेएनआई के संदर्भ में ऐसा करना है।

देशी कोड से जावा विधि को कॉल करने की पूरी प्रक्रिया सूर्य के जेएनआई गाइड पीडीएफ में "कॉलिंग विधियों" नामक धारा 4.2 में अध्याय 4 में वर्णित है, जिसे आप here पा सकते हैं।

2

invocation API पर एक नज़र डालें। यह आपको से के भीतर अपने मूल एप्लिकेशन को लोड करने और शुरू करने के लिए सक्षम बनाता है, और उसके बाद एप्लिकेशन से विधियों को आमंत्रित करने में सक्षम बनाता है।

संक्षेप में (लिंक किए गए दस्तावेज़ से)

/* load and initialize a Java VM, return a JNI interface 
* pointer in env */ 
JNI_CreateJavaVM(&jvm, &env, &vm_args); 

/* invoke the Main.test method using the JNI */ 
jclass cls = env->FindClass("Main"); 
jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V"); 
env->CallStaticVoidMethod(cls, mid, 100); 
1

निम्नलिखित समारोह आप वी एम बनाने के लिए अनुमति देता है।

JNIEnv* create_vm(JavaVM ** jvm) 
{ 
    JNIEnv *env; 
    JavaVMInitArgs vm_args; 
    JavaVMOption options[2]; 

    options[0].optionString = "-Djava.class.path=."; 
    options[1].optionString = "-DXcheck:jni:pedantic"; 

    vm_args.version = JNI_VERSION_1_6; 
    vm_args.nOptions = 2; 
    vm_args.options = options; 
    vm_args.ignoreUnrecognized = JNI_TRUE; // remove unrecognized options 

    int ret = JNI_CreateJavaVM(jvm, (void**) &env, &vm_args); 
    if (ret < 0) printf("\n<<<<< Unable to Launch JVM >>>>>\n"); 
    return env; 
} 

प्रसिद्ध Hello World प्रोग्राम संकलित करें। निम्न कार्य HelloWorld प्रोग्राम की मुख्य विधि को कॉल करने का प्रयास करता है।

int main(int argc, char* argv[]) 
{ 
    JNIEnv* env; 
    JavaVM* jvm; 

    env = create_vm(&jvm); 

    if (env == NULL) return 1; 

    jclass myClass = NULL; 
    jmethodID main = NULL; 


    myClass = env->FindClass("HelloWorld"); 


    if (myClass != NULL) 
     main = env->GetStaticMethodID(myClass, "main", "([Ljava/lang/String;)V"); 
    else 
     printf("Unable to find the requested class\n"); 


    if (main != NULL) 
    { 
     env->CallStaticVoidMethod(myClass, main, " "); 

    }else printf("main method not found") ; 


    jvm->DestroyJavaVM(); 
    return 0; 
} 

अब डाल create_vm समारोह और एक एकल cpp फ़ाइल में मुख्य कार्य, jni.h शामिल है और यह संकलन। मैंने विंडोज़ पर मिनीजीडब्ल्यू का इस्तेमाल किया।

g++ -D_JNI_IMPLEMENTATION_ -I"C:\Program Files\Java\jdk1.6.0_32\include" -I"C:\Program Files\Java\jdk1.6.0_32\include\win32" hello.cpp -L"C:\Program Files\Java\jre6\bin\client" -ljvm -o hello.exe 

Exection अब अगर आप बनाया exe चलाने के लिए, आप एक त्रुटि मिल जाएगा। jvm.dll not found। अपने पाथ पर्यावरण चर में C:\Program Files\Java\jre6\bin\client रखो। अब आप exe ​​फ़ाइल चला सकते हैं।

नोट: jvm.dll फ़ाइल को विस्थापित न करें।

0

उदाहरणों के ऊपर कोडिंग के बाद, आपको अपनी परियोजना पर कुछ कॉन्फ़िगरेशन करने की आवश्यकता है।

कदम दृश्य स्टूडियो में अपनी परियोजना के लिए jvm.lib से जोड़ने के लिए:

  • सही परियोजना पर क्लिक करें -> गुण।
  • गुण संवाद बॉक्स पर, लिंकर-> इनपुट-> अतिरिक्त निर्भरता क्षेत्र के अंतर्गत jvm.lib जोड़ें।
  • अन्त में jvm.lib पथ बारे में (जैसे "C: \ Program Files \ जावा \ jdk1.7.0_60 \ lib") के तहत Linker-> जनरल> AdditionalLibraryDirectories

उन कदमों, अपनी परियोजना कर सकते हैं के बाद जेवीएम से लिंक करें और अच्छी तरह से काम करें।

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