我刚开始使用Android NDK,但是当我在C代码中调用此代码时,我一直收到SIGSEGV:
jobjectArray someStringArray;
someStringArray = (*env)->NewObjectArray(env, 10,
(*env)->FindClass(env,"java/lang/String"),(*env)->NewStringUTF(env, ""));
基于我能找到的所有示例,上面的代码是正确的,但我一直得到SIGSERGV,如果NewObjectArray行被注释掉,一切正常。知道什么可能导致这样的问题吗?
答案 0 :(得分:5)
看起来不错,所以我猜你做错了什么。我假设你正在运行checkjni?您可能希望将其拆分为多行:执行FindClass并检查返回值,执行NewStringUTF并检查返回值,然后调用NewObjectArray。
顺便说一句,您可能希望将NULL作为最终参数传递;这种使用空字符串作为数组每个元素的默认值的模式是常用的(我认为它是从一些Sun文档中复制和粘贴并从那里传播开来的)但它很少有用,而且有点浪费。 (它与Java中“new String [10]”的行为不匹配。)
答案 1 :(得分:2)
我猜其中一个可能的原因是,在长期运行的JNI方法中,当用完每个方法调用本地参考插槽(通常是Android中的512个插槽)时,VM会中止。
由于FindClass()和NewStringUTF()函数会分配本地引用,如果长时间停留在JNI方法中,则VM不知道是否应该回收特定的本地引用。因此,您应该显式调用DeleteLocalRef()以在不再需要时释放所获取的本地引用。如果不这样做,“僵尸”本地引用将占用VM中的插槽,并且VM在所有本地参考插槽用尽时中止。
在短期JNI方法中,这可能不是问题,因为从JNI方法退出时所有本地引用都将被回收。