在 JNI Android 中调用构造函数失败

发布于 2025-01-05 09:15:34 字数 2022 浏览 0 评论 0原文

我正在尝试从 JNI Android 代码调用构造函数;但不知何故它失败了,但出现以下异常.. 我确信我错过了一些非常小的东西;但我无法弄清楚......有人可以指出吗?

 02-14 16:56:56.689: W/dalvikvm(397): JNI WARNING: JNI method called with exception raised
 02-14 16:56:56.710: W/dalvikvm(397):              in Lpv/ndk/Employee;.createWithAge (I)Lpv/ndk/Employee; (GetMethodID)

 02-14 16:56:56.710: W/dalvikvm(397): Pending exception is:
 02-14 16:56:56.710: I/dalvikvm(397): Ljava/lang/NoClassDefFoundError;: pv.ndk.Employee;
 02-14 16:56:56.723: I/dalvikvm(397):   at pv.ndk.Employee.createWithAge(Native Method)

 02-14 16:56:56.740: I/dalvikvm(397): Caused by:
 02-14 16:56:56.740: I/dalvikvm(397): Ljava/lang/ClassNotFoundException;: pv.ndk.Employee; in loader dalvik.system.PathClassLoader[/data/app/pv.ndk-2.apk]

这是我的代码:

Employee 类有 2 个构造函数和一个方法,当我调用方法 getAge() 时,该方法会令人惊讶地返回年龄

Employee()
Employee(int age)
int getAge();

。该调用会执行并获取年龄...但是当我尝试调用“Employee 构造函数”时然后尝试 getAge() 抛出此异常...

不知何故它无法找到该类: 我已经尝试了所有我遇到的 GetObjectClass() 的可能性,

这有效;当我在调用中传递 Employee 对象时,

JNIEXPORT jint JNICALL Java_pv_ndk_Employee_getAgeC(JNIEnv *env, jobject callingObject, jobject employeeObject) 
{
jclass employeeClass = env->GetObjectClass(employeeObject);
jmethodID midGetName = env->GetMethodID(employeeClass, "getAge", "()I");
int age =  env->CallIntMethod(employeeObject, midGetName);
//other code
}

这不起作用;我不知道为什么找不到班级.. 我尝试过“Lpv/ndk/Emploee”“LEmployee”“pv/ndk/Employee”..甚至尝试了以下方法:

jclass localRefCls = env->FindClass("pv/ndk/Employee");
jclass clazzEmployee = (_jclass*)env->NewGlobalRef(localRefCls);
JNIEXPORT jobject JNICALL Java_pv_ndk_Employee_createWithAge(JNIEnv *env, jobject callingObject, jint age) {
jclass employeeClass = env->FindClass("pv/ndk/Employee");
jmethodID midConstructor = env->GetMethodID(employeeClass, "<init>", "(I)V"); // BOOM SCREWED HERE .. !!
}

但每次我的代码到达 env->GetMethodID - vm 中止...

I am trying to call a constructor from my JNI Android code; but somehow it fails with the following exception..
I am sure I am missing something really small ; but I am not able to figure out ... can anyone please point out ?

 02-14 16:56:56.689: W/dalvikvm(397): JNI WARNING: JNI method called with exception raised
 02-14 16:56:56.710: W/dalvikvm(397):              in Lpv/ndk/Employee;.createWithAge (I)Lpv/ndk/Employee; (GetMethodID)

 02-14 16:56:56.710: W/dalvikvm(397): Pending exception is:
 02-14 16:56:56.710: I/dalvikvm(397): Ljava/lang/NoClassDefFoundError;: pv.ndk.Employee;
 02-14 16:56:56.723: I/dalvikvm(397):   at pv.ndk.Employee.createWithAge(Native Method)

 02-14 16:56:56.740: I/dalvikvm(397): Caused by:
 02-14 16:56:56.740: I/dalvikvm(397): Ljava/lang/ClassNotFoundException;: pv.ndk.Employee; in loader dalvik.system.PathClassLoader[/data/app/pv.ndk-2.apk]

Here is my code :

Employee class has 2 constructors and a method to return the age

Employee()
Employee(int age)
int getAge();

suprisingly when I invoke the method getAge()..the call goes through and fetches the age... But when I try to call the "Employee constructor" and then try to getAge() this exception is thrown...

somehow It is not able to find the class:
I have tried with all the possiblities I came across for GetObjectClass()

this works ; when I pass the Employee object in the call

JNIEXPORT jint JNICALL Java_pv_ndk_Employee_getAgeC(JNIEnv *env, jobject callingObject, jobject employeeObject) 
{
jclass employeeClass = env->GetObjectClass(employeeObject);
jmethodID midGetName = env->GetMethodID(employeeClass, "getAge", "()I");
int age =  env->CallIntMethod(employeeObject, midGetName);
//other code
}

THIS DOES NOT WORK ; I am not sure why it is not able to find the class..
I have tried with "Lpv/ndk/Emploee" "LEmployee" "pv/ndk/Employee" .. and even tried with the following approach:

jclass localRefCls = env->FindClass("pv/ndk/Employee");
jclass clazzEmployee = (_jclass*)env->NewGlobalRef(localRefCls);
JNIEXPORT jobject JNICALL Java_pv_ndk_Employee_createWithAge(JNIEnv *env, jobject callingObject, jint age) {
jclass employeeClass = env->FindClass("pv/ndk/Employee");
jmethodID midConstructor = env->GetMethodID(employeeClass, "<init>", "(I)V"); // BOOM SCREWED HERE .. !!
}

But everytime my code comes to env->GetMethodID - the vm Aborts ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

傲鸠 2025-01-12 09:15:34

令人惊讶的是,相同的代码今天可以工作:)

可能与我部署代码的方式有关...我相信“自动构建”应该已经解决了它...真的很抱歉在这里造成了关于工作代码的混乱片段...我是 NDK 和 JNI 开发的新手...

这绝对有效,

jclass employeeClass = env->FindClass("pv/ndk/Employee");
//constructor call depicted by <init> and it's parameters (I) and return type V
jmethodID midConstructor = env->GetMethodID(employeeClass, "<init>", "(I)V");

我认为原因可能与新修改后未部署的“本机共享库”有关...这些是我用来执行的步骤跟随 :
[1] 我通过修改重新构建了“共享库”;使用“ndk构建”
__[2] 然后我在我的设备上部署 android 项目

,但似乎 Eclipse 缓存了“库”??? [如有错误请指正]
因此,考虑到了这些更改...

解决方案:[可能]

[1] 我重建了库 __ [2] 我清理了整个项目 __ [3] 然后在设备上部署了该项目...

surprisingly the same code works today :)

probably it had to do with the way I was deploying the code... I believed that "auto build" should have taken care of it... Really sorry for creating confusion here regarding a working code snippet... I am new to NDK and JNI development ...

This definately works

jclass employeeClass = env->FindClass("pv/ndk/Employee");
//constructor call depicted by <init> and it's parameters (I) and return type V
jmethodID midConstructor = env->GetMethodID(employeeClass, "<init>", "(I)V");

I think the reason might have to do with the "native shared-library" not getting deployed after new modification... These are the steps I used to follow :
[1] I re-built the "Shared-library" with the modification ; using the "ndk-build"
__[2] Then I deploy the android project on my device

but seems Eclipse caches the "library" ??? [ please correct me if I am wrong ]
Hence the changes were taken into account...

Solution : [ possibly ]

[1] I rebuilt the library __ [2] I cleaned the whole project __ [3] then deployed the project on device...

旧人九事 2025-01-12 09:15:34

FindClass 方法需要完整的类签名。
注意:如果你有任何内部类/不起作用,你必须使用 $
例如,如果您的包名称是 ABC,主类名称是 D,子类名称是 E,那么您必须使用 FindClass("LA/B/C/D$E;");

FindClass method needs full class signature.
Note:if you have any inner classes / will not work,you have to use $
for example if your package name is A.B.C and your main class name is D and your subclass name is E then you have to use FindClass("LA/B/C/D$E;");

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文