/* * 执行对象中的方法 */ jvalue callMethod(JNIEnv *env, jboolean& hasException, jobject obj, const char *methodName, const char *descriptor, ...) { // printf("Method"); jvalue result; jobject refobj; jclass targetcls; jmethodID mid; const char *p = descriptor; //判断本地版本 // if(env->EnsureLocalCapacity(100) != JNI_OK) // { // printf("EnsureLocalCapacity == null"); // goto error; // } printf("Method11"); refobj = env->NewLocalRef(obj); printf("Method33"); targetcls = env->GetObjectClass(refobj); printf("Method1"); mid = env->GetMethodID(targetcls, methodName, descriptor); if(mid == NULL){ printf("mid == null"); env->DeleteLocalRef(targetcls); env->DeleteLocalRef(refobj); goto error; } while(*p != ')') p++; p++; va_list ap; va_start(ap, descriptor); // printf("Method2"); switch(*p){ case 'V': env->CallVoidMethodV(refobj, mid, ap); break; case '[': case 'L': result.l = env->CallObjectMethodV(refobj, mid, ap); break; case 'Z': result.z = env->CallBooleanMethodV(refobj, mid, ap); break; case 'B': result.b = env->CallByteMethodV(refobj, mid, ap); break; case 'C': result.c = env->CallCharMethodV(refobj, mid, ap); break; case 'S': result.s = env->CallShortMethodV(refobj, mid, ap); break; case 'I': result.i = env->CallIntMethodV(refobj, mid, ap); break; case 'J': result.j = env->CallLongMethodV(refobj, mid, ap); break; case 'F': result.f = env->CallFloatMethodV(refobj, mid, ap); break; case 'D': result.d = env->CallDoubleMethodV(refobj, mid, ap); break; } va_end(ap); // printf("Method3"); env->DeleteLocalRef(targetcls); env->DeleteLocalRef(refobj); error: if(env->ExceptionOccurred()) { printf("Method4"); hasException = env->ExceptionCheck(); // env->ExceptionDescribe(); // env->ExceptionClear(); // env->ThrowNew(targetcls, "error"); } return result; }