使用JNI在C ++中调用java方法

时间:2015-10-14 22:07:24

标签: java c++ java-native-interface native

我需要从c ++应用程序调用java方法。我已按照这些教程中的说明操作:http://hildstrom.com/projects/jni/index.html http://www.codeproject.com/Articles/22881/How-to-Call-Java-Functions-from-C-Using-JNI。这是我的代码:

#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;
}

我用minGW填充它,与位于“C:\ Program Files(x86)\ Java \ jdk1.7.0_79 \ lib”的jvm.lib链接。

它成功编译,但是当我执行它时只打印“启动JVM!:)”然后崩溃。  当我尝试调试时,它会在第一个GetStaticMethodID调用中崩溃。我认为它没有正确加载HelloWorld.class,但我不知道为什么。

有没有人遇到类似的问题或者想知道问题可能是什么?

我在Windows机器上64位,我使用的是java 32位,因为它没有用java 64位的jvm.lib编译。

编辑:

我添加了

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

并抛出java.lang.NoClassDefFoundError。我想我不清楚要理解什么

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

是.class文件或.jar文件的路径吗?

非常感谢!

2 个答案:

答案 0 :(得分:0)

我建议找不到类HelloWorldhello_world_class = env->FindClass("HelloWorld")调用返回null,因此hello_world_class`为null,因此使用它的下一次调用会崩溃。

您需要检查每个JNI调用的结果,无一例外。你可以对JNI一无所知。

答案 1 :(得分:0)

好的,我明白了。

我必须做两处修改:

首先我设置.jar文件的路径,包括其名称:

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

在findClass方法中,我必须指定其包名:

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

非常感谢您的回答。