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

Calling java methods in C++ using JNI

本文关键字:调用 java 方法 c++ JNI 使用      更新时间:2023-10-16

我需要从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 %dn",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 %dn", number,
        env->CallStaticIntMethod(hello_world_class, square_method, number));
    printf("%d raised to the %d power is %dn", 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编译它,与jvm链接。C:Program Files (x86)Javajdk1.7.0_79lib".

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

有没有人遇到过类似的问题,或者知道问题是什么吗?

我在64位的windows机器上,我使用java 32位,因为它不能与jvm编译。

编辑:

我添加了一个

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

抛出java.lang.NoClassDefFoundError。我想我不太明白

里面该写些什么。
options.optionString =  "-Djava.class.path=C:\Users\vhsn\workspace\AAPlugin\Debug"; 

是.class文件的路径还是.jar文件的路径?

谢谢你!

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

您需要检查每个JNI调用的结果,无一例外。

好了,我明白了。

我必须做两个改变:

首先,我设置了.jar文件的路径,包括它的名字:
char * classPath = (char *) "-Djava.class.path=HelloWorld.jar";
其次,在findClass方法中,我必须指定它的包名:
hello_world_class = env->FindClass("helloWorld/HelloWorld");

非常感谢您的回答