简体   繁体   中英

Calling java methods in C++ using JNI

I need to call java methods from a c++ application. I've followed the instructions in these tutorials: http://hildstrom.com/projects/jni/index.html http://www.codeproject.com/Articles/22881/How-to-Call-Java-Functions-from-C-Using-JNI . here is my code:

#include <stdio.h>
#include "../Header/jni.h"

JNIEnv* create_vm(JavaVM **jvm)
{
    JNIEnv* env;
    JavaVMInitArgs args;
    JavaVMOption options;
    args.version = JNI_VERSION_1_6;
    args.nOptions = 1;
    options.optionString = "-Djava.class.path= C:\\Users\\vhsn\\workspace-SP\\helloWorld\\src\\helloWorld";
    args.options = &options;
    args.ignoreUnrecognized = 0;
    int rv;
    rv = JNI_CreateJavaVM(jvm, (void**)&env, &args);
    if (rv < 0 || !env)
        printf("Unable to Launch JVM %d\n",rv);
    else
        printf("Launched JVM! :)\n");
    return env;
}

void invoke_class(JNIEnv* env)
{
    jclass hello_world_class;
    jmethodID main_method;
    jmethodID square_method;
    jmethodID power_method;
    jint number=20;
    jint exponent=3;
    hello_world_class = env->FindClass("HelloWorld");
    main_method = env->GetStaticMethodID(hello_world_class, "main", "([Ljava/lang/String;)V");
    square_method = env->GetStaticMethodID(hello_world_class, "square", "(I)I");
    power_method = env->GetStaticMethodID(hello_world_class, "power", "(II)I");
    printf("carregou metodos");
    env->CallStaticVoidMethod(hello_world_class, main_method, NULL);
    printf("%d squared is %d\n", number,
        env->CallStaticIntMethod(hello_world_class, square_method, number));
    printf("%d raised to the %d power is %d\n", number, exponent,
        env->CallStaticIntMethod(hello_world_class, power_method, number, exponent));
}

int main(int argc, char **argv)
{
    JavaVM *jvm;
    JNIEnv *env;
    env = create_vm(&jvm);
    if(env == NULL)
        return 1;
    invoke_class(env);
    return 0;
}

Im compilling it with minGW, linking with jvm.lib located at "C:\\Program Files (x86)\\Java\\jdk1.7.0_79\\lib".

It compiles successfuly, but when I execute it only prints "Launched JVM! :)" and then crashes. When I try to debug, it crashes in the first GetStaticMethodID call. Im thinking it is not loading the HelloWorld.class properly but I have no clue why.

Does anyone ever faced a similar problem or have an idea what the problem might be?

I am on a windows machine 64bits, I am using java 32 bits because it didnt compile with jvm.lib from java 64 bits.

EDIT:

I have added a

if(env->ExceptionOccurred()){
            env->ExceptionDescribe();
        }

and it throws a java.lang.NoClassDefFoundError. I think im not clearly understanding what to put in

options.optionString =  "-Djava.class.path=C:\\Users\\vhsn\\workspace\\AAPlugin\\Debug"; 

Is it the path for the .class file or the .jar file?

Thank You Very Much!

I suggest that the class HelloWorld wasn't found, the hello_world_class = env->FindClass("HelloWorld") call returned null, so hello_world_class` is null, so the next call using it crashes.

You need to check the result of every JNI call, without exception. You can assume exactly nothing with JNI.

Ok guys i got it.

I had to do two changes:

first i set the path to the .jar file including its name:

char * classPath = (char *) "-Djava.class.path=HelloWorld.jar";

Second in the findClass method,I had to specify its package name:

hello_world_class = env->FindClass("helloWorld/HelloWorld");

Thank you very much for the answers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM