How to access the Java method in a C++ application
Solution 1:
Yes you can, but it is a little convoluted, and works in a reflective/non type safe way (example uses the C++ api which is a little cleaner than the C version). In this case it creates an instance of the Java VM from within the C code. If your native code is first being called from Java then there is no need to construct a VM instance
#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();
}
To compile (on Ubuntu):
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
Note: that the return code from each of these methods should be checked in order to implement correct error handling (I've ignored this for convenience). E.g.
str = env->GetStringUTFChars(jstr, NULL);
if (str == NULL) {
return; /* out of memory */
}
Solution 2:
Yes it is, but you have to do it via JNI: http://java.sun.com/javase/6/docs/technotes/guides/jni/index.html
Solution 3:
There are many ways. Here are some ideas. In addition, commercial Java-COM bridges allow COM communication from c++ to java (if you are using Windows). You should also look at CNI.
Solution 4:
Take a look at the invocation API. This enables you to load and start up a JVM from within your native application, and then to invoke methods upon it from the application.
Briefly (from the linked doc)
/* 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);