原始的Java代码不是我的,而是来自开源库。
我觉得我做错了与记忆和处理对象的方式有关。
i_out 是从Java传入的对象,我从本机方法中设置了一些值。
这是Android Java代码中定义的方法签名:
private native int nativeXLineToRle(int i_x, int i_y, int i_len, int i_th, NyARLabeling_Rle.RleElement[] i_out, byte[] buffer, int width);
这是使用ndk-build精确编译的代码:
#include <jni.h>
JNIEXPORT jint JNICALL Java_jp_androidgroup_nyartoolkit_utils_NyARRlePixelDriverYUV420Reader_nativeXLineToRle(JNIEnv * env, jint i_x, jint i_y, jint i_len, jint i_th, jobjectArray i_out, jbyteArray buffer, jint width)
{
int current = 0;
int r = -1;
int st = i_x + width*i_y;
int x = st;
int right_edge = st + i_len - 1;
jobject anRleElement = (*env)->GetObjectArrayElement(env, i_out, 0);
jclass rleElementClass = (*env)->GetObjectClass(env, anRleElement);
jfieldID lFid = (*env)->GetFieldID(env, rleElementClass, "l", "I");
jfieldID rFid = (*env)->GetFieldID(env, rleElementClass, "r", "I");
jobject currentRleElement;
jbyte* buf = buffer;
while (x < right_edge) {
if (buf[x] > i_th) {
x++;
continue;
}
r = (x - st);
currentRleElement = (*env)->GetObjectArrayElement(env, i_out, current);
(*env)->SetIntField(env, currentRleElement, lFid, r);
r++;
x++;
while (x < right_edge) {
if (buf[x] > i_th) {
(*env)->SetIntField(env, currentRleElement, rFid, r);
current++;
x++;
r = -1;
break;
} else {
r++;
x++;
}
}
}
currentRleElement = (*env)->GetObjectArrayElement(env, i_out, current);
if (buf[x] > i_th) {
if (r >= 0) {
(*env)->SetIntField(env, currentRleElement, rFid, r);
current++;
currentRleElement = (*env)->GetObjectArrayElement(env, i_out, current);
}
} else {
if (r >= 0) {
(*env)->SetIntField(env, currentRleElement, rFid, r+1);
} else {
(*env)->SetIntField(env, currentRleElement, lFid, i_len-1);
(*env)->SetIntField(env, currentRleElement, rFid, i_len);
}
current++;
}
return current;
}
在 Android 2.3.3 设备logcat上运行代码会显示以下内容:
"Signal Catcher" daemon prio=5 tid=4 RUNNABLE
| group="system" sCount=0 dsCount=0 obj=0x4050d430 self=0x119b78
| sysTid=2343 nice=0 sched=0/0 cgrp=default handle=2511112
at dalvik.system.NativeStart.run(Native Method)
"GLThread" prio=5 tid=12 RUNNABLE
| group="main" sCount=1 dsCount=0 obj=0x40532180 self=0x2b7c20
| sysTid=2356 nice=0 sched=0/0 cgrp=default handle=2850136
at jp.androidgroup.nyartoolkit.utils.NyARRlePixelDriverYUV420Reader.nativeXLineToRle(Native Method)
at jp.androidgroup.nyartoolkit.utils.NyARRlePixelDriverYUV420Reader.xLineToRle(NyARAndYUV420GsRaster.java:268)
..............
at com.badlogic.gdx.backends.android.surfaceview.GLSurfaceViewCupcake$GLThread.run(GLSurfaceViewCupcake.java:646)
在 Android 4.1.2 设备上,我得到以下内容:
E/dalvikvm(3443): JNI ERROR (app bug): accessed stale weak global reference 0x7f (index 31 in a table of size 0)
E/dalvikvm(3443): VM aborting
A/libc(3443): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 3544 (Thread-36107)
现在我已经陷入困境,所以任何帮助都会非常感激。 提前致谢
弗朗西斯
答案 0 :(得分:0)
第21行是错误的。 jbyteArray 是一个对象,不能将转换为 jbyte * 。您应该使用JNI函数:
jbyte* buf = (*env)->GetByteArrayElements(env, buffer, NULL);
阵列应在返回之前发布:
(*env)->ReleaseByteArrayElements(env, buffer, buf, JNI_ABORT);