我试图使用jni(java本机接口)调用方法,但是当我调用该方法时它会崩溃。我阅读了文档,所以我发现我需要使用#34; jvalue"类型的对象。作为参数,但是,如何将jobject / j转换为jvalue?
这是我目前的代码:
jclass unsafeClass = (*env).FindClass("sun/misc/Unsafe");
jfieldID unsafeObjFieldID = (*env).GetStaticFieldID(unsafeClass, "theUnsafe", "Lsun/misc/Unsafe;");
jobject theUnsafe = (*env).GetStaticObjectField(unsafeClass, unsafeObjFieldID);
jmethodID defineClassID = (*env).GetMethodID(unsafeClass, "defineClass", "(Ljava/lang/String;[BIILjava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;");
jsize dataSize = (*env).GetArrayLength(arr);
jbyte* data = (*env).GetByteArrayElements(arr, NULL);
jstring name = (*env).NewStringUTF("Test");
jint n0 = (jint) 0;
// In this method it crashes ._.
(*env).CallObjectMethod(theUnsafe, defineClassID, name, data, n0, dataSize, classLoader, NULL);
hs_err_pid(如果有帮助):http://paste.reflex.rip/okugaluyok.go
编辑:我找到了启动参数" -Xcheck:jni",现在我收到了一些错误消息。FATAL ERROR in native method: Bad JNI oop argument
答案 0 :(得分:0)
我知道这是旧的和过时的,但这似乎是唯一带有此特定错误消息的线程。我没有与OP相同的设置,但我发现当我尝试这样做时
env->CallStaticVoidMethod(jcls, mainMethod);
我会收到同样的错误。这是为了调用我的主类的主要静态方法。它还产生了相同的错误消息" Bad JNI oop argument"。
我通过创建一个新的(空)jobjectArray并将其传递给方法来解决这个问题,并修复了我的错误。
jobjectArray args;
args = env->NewObjectArray(0, env->FindClass("java/lang/String"), 0);
env->CallStaticVoidMethod(jcls, mainMethod, args);
答案 1 :(得分:-1)
(*env).CallObjectMethod(theUnsafe, defineClassID, name, data, n0, dataSize, classLoader, NULL);
这不正确。你搞定了吗?不要那样做。阅读JNI Specification。它应该是:
env->CallObjectMethod(theUnsafe, defineClassID, name, data, n0, dataSize, classLoader, NULL);
为了完整起见,在C中它应该是:
(*env)->CallObjectMethod(env, theUnsafe, defineClassID, name, data, n0, dataSize, classLoader, NULL);