6

我刚开始使用 Android NDK,但是当我在 C 代码中调用此调用时,我不断收到 SIGSEGV:

jobjectArray someStringArray;
someStringArray = (*env)->NewObjectArray(env, 10, 
(*env)->FindClass(env,"java/lang/String"),(*env)->NewStringUTF(env, ""));

根据我能找到的所有示例,上面的代码是正确的,但我不断收到 SIGSERGV,如果 NewObjectArray 行被注释掉,一切都很好。知道什么会导致这样的问题吗?

4

2 回答 2

5

看起来是对的,所以我猜你做错了什么。我假设您正在使用 checkjni 运行?您可能希望将其分成多行:执行 FindClass 并检查返回值,执行 NewStringUTF 并检查返回值,然后调用 NewObjectArray。

顺便说一句,您可能希望将 NULL 作为最后一个参数传递;这种使用空字符串作为数组每个元素的默认值的模式很常用(我认为它是从一些 Sun 文档中复制和粘贴的,并且已经从那里传播开来),但它很少有用,而且有点浪费。(并且它与 Java 中“new String[10]”的行为不匹配。)

于 2010-01-23T21:34:28.480 回答
2

我猜可能的原因之一是在长期运行的 JNI 方法中,当每个方法调用的本地引用槽(通常在 Android 中为 512 个槽)用完时,VM 会中止。

由于 FindClass() 和 NewStringUTF() 函数会分配局部引用,如果你长时间停留在 JNI 方法中,VM 不知道是否应该回收特定的局部引用。因此,您应该在不再需要时显式调用 DeleteLocalRef() 以释放获取的本地引用。如果不这样做,“僵尸”本地引用将占用 VM 中的插槽,并且 VM 在用完所有本地引用插槽时中止。

在短期 JNI 方法中,这可能不是问题,因为从 JNI 方法退出时所有本地引用都将被回收。

于 2011-08-12T19:32:00.657 回答