我在cpp(本机JNI)中获取实际jar文件的路径时遇到问题,有人可以给我一些提示吗? 我的CodeSource工作项目为NULL
jclass thisObj = env->FindClass("Main");
jmethodID firstMid = env->GetMethodID(thisObj, "<init>", "()V");
jobject firstObjClass = env->NewObject(thisObj, firstMid);
jclass main = env->GetObjectClass(firstObjClass);
jmethodID mid = env->GetMethodID(main, "getClass", "()Ljava/lang/Class;");
if (mid == 0) return;
jobject objClass = env->CallObjectMethod(thisObj, mid);
jclass clsclass = env->GetObjectClass(objClass);
jmethodID midPD = env->GetMethodID(clsclass, "getProtectionDomain", "()Ljava/security/ProtectionDomain;");
if (midPD == 0)return;
jobject objPD = env->CallObjectMethod(objClass, midPD);
jclass clsPD = env->GetObjectClass(objPD);
jmethodID midCS = env->GetMethodID(clsPD, "getCodeSource", "()Ljava/security/CodeSource;");
jobject objCS = env->CallObjectMethod(objPD, midCS);
jclass clscs = env->GetObjectClass(objCS);
jmethodID locMethod = env->GetMethodID(clscs, "getLocation", "()Ljava/net/URL");
jobject locObj = env->CallObjectMethod(objCS, locMethod);
jclass locClass = env->GetObjectClass(locObj);
jmethodID pathMethod = env->GetMethodID(locClass, "getPath", "()Ljava/lang/String");
jobject path = env->CallObjectMethod(locObj, pathMethod);
cout << path << endl;
return;
}
答案 0 :(得分:1)
我肯定会在Java类中添加一些辅助方法。但是您也可以从JNI做到这一点。
// Now, let's get it hard way. Let's make a hell lot of JNI based calls
// Note! I don't care for error handling - but you should check whether
// each call produced something sensible or not
jmethodID method_Main_init = (*env)->GetMethodID(env, cls_Main, "<init>", "()V");
jobject obj_Main = (*env)->NewObject(env, cls_Main, method_Main_init);
jmethodID method_getClass = (*env)->GetMethodID(env, cls_Main, "getClass", "()Ljava/lang/Class;");
jobject obj_Class = (*env)->CallObjectMethod(env, obj_Main, method_getClass);
jclass cls_Class = (*env)->GetObjectClass(env, obj_Class);
jmethodID method_getProtectionDomain = (*env)->GetMethodID(env, cls_Class, "getProtectionDomain", "()Ljava/security/ProtectionDomain;");
jobject obj_ProtectionDomain = (*env)->CallObjectMethod(env, obj_Class, method_getProtectionDomain);
jclass cls_ProtectionDomain = (*env)->GetObjectClass(env, obj_ProtectionDomain);
jmethodID method_getCodeSource = (*env)->GetMethodID(env, cls_ProtectionDomain, "getCodeSource", "()Ljava/security/CodeSource;");
jobject obj_CodeSource = (*env)->CallObjectMethod(env, obj_ProtectionDomain, method_getCodeSource);
jclass cls_CodeSource = (*env)->GetObjectClass(env, obj_CodeSource);
jmethodID method_getLocation = (*env)->GetMethodID(env, cls_CodeSource, "getLocation", "()Ljava/net/URL;");
jobject obj_URL = (*env)->CallObjectMethod(env, obj_CodeSource, method_getLocation);
jclass cls_URL = (*env)->GetObjectClass(env, obj_URL);
jmethodID method_toURI = (*env)->GetMethodID(env, cls_URL, "toURI", "()Ljava/net/URI;");
jobject obj_URI = (*env)->CallObjectMethod(env, obj_URL, method_toURI);
jclass cls_File = (*env)->FindClass (env, "java/io/File");
jmethodID method_File_init = (*env)->GetMethodID(env, cls_File, "<init>", "(Ljava/net/URI;)V");
jobject obj_File = (*env)->NewObject(env, cls_File, method_File_init, obj_URI);
jmethodID method_getPath = (*env)->GetMethodID(env, cls_File, "getPath", "()Ljava/lang/String;");
jobject obj_String = (*env)->CallObjectMethod(env, obj_File, method_getPath);
// Finally, we have path, all we have to do is to "cast" it to char *
// and print it
const char *c_str;
c_str = (*env)->GetStringUTFChars(env, obj_String, NULL);
if(c_str != NULL) {
printf("Path from JNI: %s\n", c_str);
} else {
printf("Something went wrong :(");
}
有关示例代码,请在此处查看:https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo050
为什么会失败
它失败了,因为到处都是jclass
和jobject
的混合体(也缺少分号)。这就是为什么我的代码不仅格式正确,而且还能正常工作的原因;)如果您想了解代码中的损坏之处,请随时将您的版本与以下代码进行比较。
jclass thisObj = (*env)->FindClass(env, "Main");
jmethodID firstMid = (*env)->GetMethodID(env, thisObj, "<init>", "()V");
jobject firstObjClass = (*env)->NewObject(env, thisObj, firstMid);
jclass main = (*env)->GetObjectClass(env, firstObjClass);
jmethodID mid = (*env)->GetMethodID(env, main, "getClass", "()Ljava/lang/Class;");
jobject objClass = (*env)->CallObjectMethod(env, firstObjClass, mid);
jclass clsclass = (*env)->GetObjectClass(env, objClass);
jmethodID midPD = (*env)->GetMethodID(env, clsclass, "getProtectionDomain", "()Ljava/security/ProtectionDomain;");
jobject objPD = (*env)->CallObjectMethod(env, objClass, midPD);
jclass clsPD = (*env)->GetObjectClass(env, objPD);
jmethodID midCS = (*env)->GetMethodID(env, clsPD, "getCodeSource", "()Ljava/security/CodeSource;");
jobject objCS = (*env)->CallObjectMethod(env,objPD, midCS);
jclass clscs = (*env)->GetObjectClass(env, objCS);
jmethodID locMethod = (*env)->GetMethodID(env, clscs, "getLocation", "()Ljava/net/URL;");
jobject locObj = (*env)->CallObjectMethod(env, objCS, locMethod);
jclass locClass = (*env)->GetObjectClass(env, locObj);
jmethodID pathMethod = (*env)->GetMethodID(env, locClass, "getPath", "()Ljava/lang/String;");
jobject path = (*env)->CallObjectMethod(env, locObj, pathMethod);