Embed Java into a C++ application?
Solution 1:
You can embed a JVM within your application. Oracle's official reference book has some more details. The synopsis of it is:
#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(); }
You can do far more sophisticated things if you want (e.g. custom class loaders) but that's about it in terms of the bare minimum needed to get a JVM working within your application.
Solution 2:
There seems to be some confusion over whether you want to embed Java into the C++ app or the other way around. I will take each case.
For embedding java into c++ app, you can make a socket call to the java program. On java end, you use SocketServer and on the C++ end, you use the General Socket Layer library. This is by far the easiest and most scalable approach. As your java workload keeps increasing, you keep adding additional jvm. Slightly complicated to deploy but, it works really well.
For embedding C++ app in java. This is simple. You compile C++ app into a shared library and use JNI to invoke it.
Solution 3:
What I basically want to do is to embed Java into this application. This has already been done with Python (not done by me).
The JNI Invocation API supports this, as described by @awoodland. Here's a current link, for Java 6/7.
What I'd like to do is, to use classes from C++ in Java to interact with the application. It's a 3D app in this case, called Cinema 4D.
For this you could use one of the following:
- Java native methods implemented in C
- JNA
- SWIG
Is there a way to compile and evaluate Java code while the application is running (in some sort of scripting language) using JNI or anything like it ?
BeanShell or Groovy, among others, might be of interest to you. Both support dynamically interpreted code that runs on the JVM.
Solution 4:
I've been working in something similar lately. What worked for me was using the library jni.h that comes when you install java (Java\jdk[version]\include) and creating a dll with c/c++ code in visual studio. For example:
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");
}
Then create a dll with Visual Studio and load the dll within a static block. I didn't try that without compiling the c/c++ code in a dll, maybe there's another way to call the c/c++ code. But that's how you implement it.
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
So, you just do that and implement java methods with all c/c++ you want.
If you still don't know how to do it, enlighten yourself here:
Java Native Interface Specification - Oracle
Java Native Interface - Wikipedia