JNI“env-> GetStaticMethodID()"崩溃的程序 [英] JNI "env->GetStaticMethodID()" crashed program

查看:742
本文介绍了JNI“env-> GetStaticMethodID()"崩溃的程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从C ++调用Java函数。
这是我到目前为止的代码:

I'm trying to call a Java function from C++. This is my code so far:

#include <jni.h>

typedef struct JavaVMCreationResult {
    JavaVM* jvm;
    JNIEnv* env;
} JVMCreationResult;

JVMCreationResult* CreateJavaVM() {
    JavaVM* jvm;
    JNIEnv* env;

    JavaVMInitArgs args;

    JavaVMOption opts[1];
    opts[0].optionString = "-Djava.class.path=C:\\MyJavaClasses";

    args.version = JNI_VERSION_1_6;
    args.nOptions = 1;
    args.options = opts;
    args.ignoreUnrecognized = JNI_TRUE;

    JNI_GetDefaultJavaVMInitArgs(&args);

    JNI_CreateJavaVM(&jvm, (void **) &env, &args);

    JavaVMCreationResult* cres;
    cres->jvm = jvm;
    cres->env = env;

    return cres;
}

int main() {
    JVMCreationResult* cres = CreateJavaVM();
    JavaVM* jvm = cres->jvm;
    JNIEnv* env = cres->env;

    jclass cls = env->FindClass("Main");
    jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); // the evil line
}

我正在使用Code :: Blocks with MinGW GCC在Windows 7上。

main()函数的最后一行使程序崩溃,但编译器不会抱怨任何内容。 (注释 jmethodID mid = env-> GetSta ... 行使程序不崩溃)

我使用 javap -s Main 获取正确的方法签名,该类也是一个有效的Java类。

I'm using Code::Blocks with MinGW GCC on Windows 7.
The last line in the main() function crashes the Program, but the compiler does not complain about anything. (Commenting out the jmethodID mid = env->GetSta... line makes the program "not crashing")
I have uses javap -s Main to obtain the right method signature, also the class is a valid Java class.

你能告诉我为什么程序崩溃了吗?这个例子只是在互联网上随处可见,但它对我不起作用。 :(

Can you tell me why the Program crashes ? This example is just shown everywhere on the Internet but it doesn't work for me. :(

这是Java类:

public class Main {
    public static void main(String[] args) {
        System.out.println("This is from Java !");
    }
}



解决方案



我不会想到它,似乎对于我来说,没有初始化结构时程序没有崩溃。但这确实是问题。

这是完整且正常工作的代码!

SOLUTION

I wouldn't have thought it, it seems unlogic to me that the program wasn't crashing earlier when the struct wasn't initialized. But this was really the issue.
This is the full and working code !

#include <jni.h>

#ifndef null
#define null NULL
#endif

typedef struct JavaVMCreationResult {
    JavaVM* jvm;
    JNIEnv* env;
} JVMCreationResult;

JVMCreationResult* CreateJavaVM() {
    JavaVM* jvm;
    JNIEnv* env;

    JavaVMInitArgs args;

    JavaVMOption opts[1];
    opts[0].optionString = "-Djava.class.path=C:\\Users\\Claudia\\Desktop";

    args.version = JNI_VERSION_1_6;
    args.nOptions = 1;
    args.options = opts;
    args.ignoreUnrecognized = JNI_TRUE;

    JNI_GetDefaultJavaVMInitArgs(&args);

    JNI_CreateJavaVM(&jvm, (void **) &env, &args);

    JVMCreationResult* cres = new JVMCreationResult();
    cres->jvm = jvm;
    cres->env = env;

    return cres;
}

int main() {
    JVMCreationResult* cres = CreateJavaVM();
    JavaVM* jvm = cres->jvm;
    JNIEnv* env = cres->env;

    jclass cls = env->FindClass("Main");
    if (cls) {
        printf("Yes !\n");
    }
    else {
        printf("No !\n");
    }
    jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
    env->CallStaticVoidMethod(cls, mid);

    printf("At end of Program.");
}


推荐答案

你的变量cres是CreateJavaVM调用中从未初始化的一个点,因此您可能在该点取消引用null或其他无效指针。

Your variable "cres" is a point in the CreateJavaVM call that is never initialized, so you're probably dereferencing a null or otherwise invalid pointer at that point.

一种解决方案是定义cres(不是在main中指向cres的指针,并将指向的指针传递给CreateJavaVM作为参数,然后使用CreateJavaVM中的参数返回结果。

One solution is to define cres (not a pointer to cres) in main, and pass a pointer to that to CreateJavaVM as a parameter, and then use the parameter inside CreateJavaVM to return the result.

在JNI_CreateJavaVM调用之后检查jvm和env是否获得非空值是个好主意,并且在分别调用FindClass和GetStaticMethodID后cls和mid同样是非空的

Also it's a good idea to check that jvm and env get non-null values after the JNI_CreateJavaVM call, and that cls and mid are likewise non-null after the calls to FindClass and GetStaticMethodID, respectively

这篇关于JNI“env-&gt; GetStaticMethodID()&quot;崩溃的程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆