当我调用CallVoidMethodA时程序崩溃

时间:2015-04-29 12:53:06

标签: java java-native-interface

我尝试从c调用几个非静态java方法。我检查过任何对象,方法或env变量是否为null,都不是。当我使用静态方法而不是非静态方法

时,该程序运行良好
JavaVM *jvm;
jobject g_obj;
jmethodID g_mid;

void func(){
  jclass DTK_ANPR_Test;
  jmethodID dtk_anpr;
  DTK_ANPR_Test = (*env)->FindClass(env, "DTKANPRTest");
  g_mid = (*env)->GetMethodID(env, DTK_ANPR_Test, "anpr", "(I)V");
  jobject obj = (*env)->NewObjectA(env, DTK_ANPR_Test, g_mid, val);
  g_obj = (*env)->NewGlobalRef(env, DTK_ANPR_Test);

}

我致电(*env)->CallVoidMethodA(env, g_obj, g_mid, val);   从同一方法或另一种方法,该程序崩溃。是对象还是别的问题?

P.S。我使用AttachCurrentThreadDetachCurrentThread从本机代码

再次调用该方法

P.S。还有另一个类似的线程,它没有解决我的问题: JNI crashes when calling CallVoidMethod

1 个答案:

答案 0 :(得分:0)

要从GetMethodId返回类的构造函数,请将<init>作为方法名称,而不是类名。来自the docs

  

jobject NewObjectA(JNIEnv * env,jclass clazz,   jmethodID methodID,const jvalue * args);

     

构造一个新的Java对象。方法ID指示要调用的构造方法。必须通过调用GetMethodID()并将<init>作为方法名称并将void(V)作为返回类型来获取此ID。

所以将代码更改为:

g_mid = (*env)->GetMethodID(env, DTK_ANPR_Test, "<init>", "(I)V");

此外,您不能使用NewObjectA保存对正在创建的对象的引用。将您的代码更改为:

g_obj = (*env)->NewGlobalRef(env, obj);

您的代码用于静态方法的原因是在调用静态方法时使用了类对象而不是对象实例。