2012-04-03 19 views
1

ネイティブCコードで効率的に作成および更新された配列にアクセスしたい。必要があれば、私はポインタまたはJavaコードからネイティブ側への参照を送信し、Cコードがそれを消費する準備ができたらSDK側から読むことができるようにそれを読み込ませることができます。JNI経由でJava(SDK)のネイティブコード(NDK)にアクセスする

現在、私はこれをやっています。しかし、私はそれを行うより良い方法があると思う、私は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; 
} 

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

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

答えて

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側で同じであることを確認してください。

+0

これは良いスタートです。私はgetValues()を呼び出すたびにJava側でdouble []オブジェクトの作成を保存することは可能ですか?私たちはネイティブ側へのポインタを渡し、配列をそこに設定してsdk側で読むことができますか?どうも。 –

+0

絶対に。ネイティブメソッドで 'jdoubleArray'パラメータを導入し、Java側で配列を作成し、それをJNIに渡して値を入力します。サイズマッチングには注意してください。 –

+0

Thx @Seva Alekseyev –

関連する問題