C++ JNI

Da Andreabont's Wiki.

Da C++ è possibile chiamare la macchina virtuale Java ed eseguire codice java attraverso l'interfaccia JNI.

Compilare

g++ -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -L /usr/bin/java -L $JAVA_HOME/jre/lib/amd64/server -ljvm <codice.cpp>

Sorgente

Inizializzazione della JVM

#include <jni.h>
#include <iostream>

int main() {

    JavaVM *jvm;                                     // Puntatore alla JVM
    JNIEnv *env;                                     // Puntatore all'ambiente
    JavaVMInitArgs vm_args;                          // Argomenti per la JV;
    JavaVMOption* options = new JavaVMOption[1];     // Opzioni per la JVM
    options[0].optionString = "-Djava.class.path=."; // Path dei file .class
    vm_args.version = JNI_VERSION_1_6;               // minimum Java version
    vm_args.nOptions = 1;                            // Numero di opzioni inserite
    vm_args.options = options;                       // Carico opzioni negli argomenti
    vm_args.ignoreUnrecognized = false;              // Opzioni non riconosciute generano errori
    jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    delete options;

    if (rc != JNI_OK) {
        // ERRORE!!!
    }

    // Tutto OK...

    jvm->DestroyJavaVM();                            // Distruggo JVM

}

Chiamare un metodo statico

Poniamo di avere la seguente classe Java:

public class Test {

     public static void PrintHello() { 
         System.out.println("Hello, World!!");
     }

     public static int Mul(int n) {
         return n*2; 
     }

}

Possiamo chiamare il metodo statico PrintHello da C++ in questo modo:

jclass cls2 = env->FindClass("Test");  // Cerca la classe Test nel path indicato nelle opzioni

if(cls2 == nullptr) {
    // ERRORE!!
}

jmethodID metodo_hello = env->GetStaticMethodID(cls2, "PrintHello", "()V");  // Cerca il metodo statico PrintHello
jmethodID metodo_mul = env->GetStaticMethodID(cls2, "Mul", "(I)I");          // Cerca il metodo statico Mul

if(metodo_hello == nullptr || metodo_mul == nullptr) {
    // ERRORE!
}

env->CallStaticVoidMethod(cls2, metodo_hello);                 // Chiama il metodo PrintHello
int ret = env->CallStaticIntMethod(cls2, metodo_mul, (jint)5); // Chiama il metodo Mul con parametro 5
cout << "Risultato chiamata Mul: " << ret << endl;