1

申し訳ありませんが、オブジェクトは少し一般的に見えるかもしれませんが、Android NDK開発の経験がなく、Javaメソッドをネイティブコードに変換しようとしていますが、いくつかの問題が発生しています。

元のJavaコードは私のものではなく、オープンソースライブラリから取得されます。

記憶や物の扱い方に問題があるような気がします。

i_outは、Javaから渡されたオブジェクトであり、ネイティブメソッド内からいくつかの値を設定します。

これは、AndroidJavaコードで定義されているメソッドシグネチャです。

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)

今はかなり行き詰まっているので、どんな助けでも大歓迎です。前もって感謝します

フランチェスコ

4

1 に答える 1

0

21行目が間違っています。jbyteArrayはオブジェクトであり、jbyte*にキャストすることはできません。そのためには、JNI関数を使用する必要があります。

jbyte* buf = (*env)->GetByteArrayElements(env, buffer, NULL);

配列は戻る前に解放する必要があります:

(*env)->ReleaseByteArrayElements(env, buffer, buf, JNI_ABORT);
于 2013-01-20T15:52:12.750 に答える