1

ネイティブCコードで作成および更新された配列に効率的にアクセスしたい。必要に応じて、Javaコードからネイティブ側にポインターまたは参照を送信し、Cコードにデータを入力して、使用する準備ができたときにSDK側から読み取ることができるようにすることができます。

現在、これは私がそれをしている方法です。しかし、C側で1つのコピーを実行し、Java側で読み取りを発行するたびに作成されるオブジェクトがあるため、より良い方法があると思います。

私のJavaコード:

double[] valuesFromNative = getValues();
public static native double[] getValues();
static { System.loadLibrary("test-jni"); }

私のネイティブ(C ++ではなくC)コード:

#define LEN 18
double testDoubleArr[LEN];
jdoubleArray Java_com_test_testActivity_getValues(JNIEnv *env, jclass clazz) {
    jboolean isCopy;
    int i;
    jdoubleArray result = (*env)->NewDoubleArray(env, LEN);
    jdouble* destArrayElems = (*env)->GetDoubleArrayElements(env, result, &isCopy);
    for (i = 0; i < LEN; i++) {
       destArrayElems[i] = testDoubleArr[i];
    }
    if(isCopy == JNI_TRUE) {
        //  isCopy should NEVER be JNI_TRUE in this case, right?
        // so, i could as well replace this condition with
        // assert(isCopy == JNI_FALSE)?
    }
return result;
}

このコードスニペットは機能します-したがって、私は同じことを達成するためのより効率的またはむしろ正しい方法を探しています。

あなたの考えを共有してくれてありがとう。

4

1 に答える 1

2

SetDoubleArrayRegion()もっと速いと思います。コードと JNI 呼び出しが少ないことは確かです。

jdoubleArray result = (*env)->NewDoubleArray(env, LEN); 
(*env)->SetDoubleArrayRegion(env, result, 0, LEN, testDoubleArr);

C++ 側で配列を作成する必要さえありません。次のようにメソッドを宣言します。

public static native void getValues(double[] a);   

次のように実装します。

void Java_com_test_testActivity_getValues(JNIEnv *env, jclass clazz, jdoubleArray a)
{//...

Java 側で配列を作成し、それをインスタンス変数などにキャッシュし、JNI に渡して必要なときにいつでも入力できるようにします。配列サイズに関する仮定が Java 側と C 側で同じであることを確認してください。

于 2012-04-03T02:42:20.193 に答える