2011-09-21 15 views
17

मुझे सी ++ में लिखा गया एक एप्लीकेशन मिला है और मैं इसके लिए सी ++ में प्लगइन लिखकर एप्लिकेशन कार्यक्षमता का विस्तार करने में सक्षम हूं।जावा को एक C++ एप्लिकेशन में एम्बेड करें?

मैं मूल रूप से ऐसा करना चाहता हूं कि जावा को इस एप्लिकेशन में एम्बेड करना है। यह पहले से ही पाइथन (मेरे द्वारा नहीं किया गया) के साथ किया जा चुका है।

मैंने जेएनआई के बारे में कुछ पढ़ा लेकिन जावा कक्षाओं का उपयोग करने वाले एक पूर्ण प्रोग्राम से हमेशा भाषण होता है।

मैं क्या करना चाहता हूं, जावा में सी ++ से कक्षाओं का उपयोग करने के लिए आवेदन के साथ बातचीत करने के लिए।
यह इस मामले में एक 3 डी ऐप है, जिसे सिनेमा 4 डी कहा जाता है।

क्या जेएनआई या कुछ भी इस तरह का उपयोग करते हुए एप्लिकेशन चल रहा है (कुछ प्रकार की स्क्रिप्टिंग भाषा में) जावा कोड को संकलित और मूल्यांकन करने का कोई तरीका है?

उदाहरण काल्पनिक कोड के बाद एम्बेडिंग किया गया था:

import c4d.documents.*; 

class Main { 
    public static void main() { 
    BaseDocument doc = GetActiveDocument(); 
    BaseObject op = doc.GetActiveObject(); 
    if (op != null) { 
     op.Remove(); 
    } 
    } 
} 

इस कोड सिनेमा 4D के साथ बातचीत करनी चाहिए चयनित ऑब्जेक्ट को हटाने के लिए।

+0

आप पूर्ण जावा एसई या सिर्फ कुछ न्यूनतम वी एम की ज़रूरत है? –

+0

आप "कुछ प्रकार की स्क्रिप्टिंग भाषा" क्यों कहते हैं, अगर आप पहले ही निर्धारित कर चुके हैं कि यह भाषा जावा होनी चाहिए? – jalf

+0

@ माइकलराजर यह वास्तव में अभी भी खुला है, जावा के बीच मूल बातचीत और एप्लिकेशन शुरुआत के लिए बहुत अच्छा होगा। –

उत्तर

37

आप अपने आवेदन के भीतर एक जेवीएम एम्बेड कर सकते हैं। ओरेकल के official reference book में कुछ और विवरण हैं। इसके बारे में सार है:

#include <jni.h>  /* where everything is defined */ 

int main() { 
    JavaVM *jvm;  /* denotes a Java VM */ 
    JNIEnv *env;  /* pointer to native method interface */ 
    JDK1_1InitArgs vm_args; /* JDK 1.1 VM initialization arguments */ 
    vm_args.version = 0x00010001; /* New in 1.1.2: VM version */ 
    /* Get the default initialization arguments and set the class 
    * path */ 
    JNI_GetDefaultJavaVMInitArgs(&vm_args); 
    vm_args.classpath = ...; 
    /* 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); 
    /* We could have created an Object and called methods on it instead */ 
    /* We are done. */ 
    jvm->DestroyJavaVM(); 
} 

यदि आप (जैसे कस्टम वर्ग लोडर) चाहते अधिक परिष्कृत कर सकते हैं, लेकिन यह एक JVM के भीतर काम कर पाने के लिए की जरूरत न्यूनतम के मामले में इसके बारे में आपका आवेदन।

+0

अब, यह जावा विधि को C++ से कॉल करने के लिए नहीं है? मुझे वास्तव में इसे दूसरी तरफ की आवश्यकता होगी :) –

+2

स्विग के साथ आप बाइंडिंग जेनरेट कर सकते हैं जो आपको जावा से सी ++ पर कॉल करने देता है। सवाल यह है कि आप इसे इस तरह से चाहते थे। आप दोनों एक कार्यक्रम में भी कर सकते हैं। – Flexo

+0

मेरे दो सेंट: चूंकि ओपी प्लगइन्स लोड करना चाहता है, मुझे लगता है कि उसे यह भी पढ़ना चाहिए कि कस्टम क्लास लोडर उसे "प्लगइन जार" कैसे पढ़ने की अनुमति देता है। इसके अलावा, आपको Java से C++ को कॉल करने के लिए मूल विधियों (यानी जेएनआई) के साथ जावा क्लासेस की आवश्यकता है। –

0

परिदृश्य के लिए आप जेएनआई का वर्णन कर रहे हैं शायद जाने का सबसे अच्छा तरीका है। आप अपने सी ++ ऐप की कार्यक्षमता को एक डीएलएल के रूप में उजागर करेंगे जिसे जावा एप्लिकेशन में शामिल और उपयोग किया जा सकता है।

-1

आपको शायद अपने डिज़ाइन पर पुनर्विचार करने की आवश्यकता है। जावा इस तरह के कार्यों के लिए एक अच्छा विकल्प नहीं है। जावा मानक लाइब्रेरी में eval() के समान पाइथन या खोल से eval() फ़ंक्शन नहीं है।

आप जेएनआई का उपयोग कर सी ++ कोड में जावा वीएम बना सकते हैं लेकिन यह बहुत भारी है। जावा स्रोत से बाइटकोड बनाने का तरीका अभी भी जारी है। आपको C++ में जावा कोड संकलित करने और चलाने के लिए बहुत सारे कोड एम्बेड करना होगा। ऐसा मत करो। बेहतर समाधान होना चाहिए।

उदाहरण के लिए आप अपने सी ++ कोड और अलग जावा कोड के बीच कुछ आरपीसी (एसओएपी, एक्सएमएल-आरपीसी, कॉर्बा) का उपयोग कर सकते हैं। यदि आपको जावा आमंत्रण के समान कुछ eval() करने की आवश्यकता है, तो आप ग्रोवी या ज्योथन (दोनों eval(), सभी मानक जावा लाइब्रेरी तक पहुंच सकते हैं और नियमित जावा कक्षाएं चला सकते हैं) का उपयोग कर सकते हैं।

2

क्या मैं मूल रूप से क्या करना चाहते हैं इस आवेदन में जावा एम्बेड करने के लिए है। यह पहले से ही पाइथन (मेरे द्वारा नहीं किया गया) के साथ किया जा चुका है।

जेएनआई आमंत्रण API इसका समर्थन करता है, जैसा कि @awoodland द्वारा वर्णित है। Here's a current link, for Java 6/7

मैं क्या करना चाहता हूं, जावा में सी ++ से कक्षाओं का उपयोग करने के लिए पर एप्लिकेशन के साथ बातचीत करने के लिए। यह इस मामले में एक 3 डी ऐप है, जिसे सिनेमा 4 डी कहा जाता है।

इसके लिए

आप निम्न में से एक का उपयोग कर सकता:

  • जावा देशी सी
  • JNA
  • SWIG

में लागू तरीकों वहाँ संकलित करने के लिए एक रास्ता है और अनुप्रयोगके दौरान जावा कोड का मूल्यांकन करें जेएनआई या कुछ भी का उपयोग करचल रहा है (कुछ प्रकार की स्क्रिप्टिंग भाषा में)?

BeanShell या Groovy, दूसरों के बीच, आप के हित के लिए हो सकता है। दोनों समर्थन गतिशील रूप से कोड का अर्थ है जो JVM पर चलता है।

+0

जावा से सी ++ को कॉल करने के लिए, मैं [BridJ] (http://code.google.com/p/bridj) + [JNAerator] (http://code.google.com/p] पर एक नज़र डालने की भी सिफारिश करता हूं (http://code.google.com/p/jnaerator)। – zOlive

3

ऐसा कुछ भ्रम प्रतीत होता है कि आप जावा को C++ ऐप या अन्य तरीकों से एम्बेड करना चाहते हैं या नहीं। मैं हर मामले ले जाऊंगा।

  1. जावा + C++ ऐप में एम्बेड करने के लिए, आप जावा प्रोग्राम में सॉकेट कॉल कर सकते हैं। जावा अंत में, आप सॉकेटसेवर का उपयोग करते हैं और सी ++ अंत में, आप सामान्य सॉकेट लेयर लाइब्रेरी का उपयोग करते हैं। यह अब तक का सबसे आसान और सबसे स्केलेबल दृष्टिकोण है। चूंकि आपका जावा वर्कलोड बढ़ता रहता है, आप अतिरिक्त जेवीएम जोड़ते रहते हैं। तैनात करने के लिए थोड़ा जटिल लेकिन, यह वास्तव में अच्छी तरह से काम करता है।

  2. जावा में सी ++ ऐप एम्बेड करने के लिए। यह सरल है। आप सी ++ ऐप को साझा लाइब्रेरी में संकलित करते हैं और इसे आमंत्रित करने के लिए जेएनआई का उपयोग करते हैं।

1

मैं हाल ही में कुछ इसी तरह से काम कर रहा हूं। मेरे लिए क्या काम किया गया लाइब्रेरी jni.h का उपयोग कर रहा था जो तब आता है जब आप जावा (जावा \ jdk [version] \ include) स्थापित करते हैं और विजुअल स्टूडियो में सी/सी ++ कोड के साथ एक डीएल बनाते हैं। उदाहरण के लिए:

Test.h

//declare the method you want to implement in c/c++ in the header 
//include the jni header 
#include <jni.h> 
JNIEXPORT void JNICALL Java_Test_print(JNIEnv *, jobject); 
//Java_[Class Name]_[Method Name](pointer to JVM, java object); 

Test.cpp

extern "C" JNIEXPORT void JNICALL Java_WinampController_printTrackInfo (JNIEnv *env, jobject obj){ 
    printf("Hey, I'm a java method in c (or not?)\n"); 
} 

फिर दृश्य स्टूडियो के साथ एक dll बना सकते हैं और एक स्थिर ब्लॉक के भीतर DLL लोड। मैंने कोशिश नहीं की कि एक डीएल में सी/सी ++ कोड संकलित किए बिना, शायद सी/सी ++ कोड को कॉल करने का दूसरा तरीका है। लेकिन इस तरह आप इसे कार्यान्वित करते हैं।

Test.java

//declare the same method native inside a class in java 
public class Test{ 
    static { 
     System.loadLibrary("Test"); //load the dll 
    } 
    public native void print(); 
} //after that you just call test.print() normally 

तो, ठीक यही करने और सभी C/C++ आप चाहते हैं के साथ जावा तरीकों को लागू।

आप अभी भी इसे कैसे करना है पता नहीं है, अपने आप को यहाँ प्रबुद्ध:

Java Native Interface Specification - Oracle

Java Native Interface - Wikipedia

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