C++で書かれたJNI関数を使用して、バイト配列を入力としてセグメント化し、バイト配列の配列をJavaに返します。C++でbyte [] []を作成し、JNIを使用してJavaに戻す
JNIEXPORT jobjectArray JNICALL Java_class_method(JNIEnv * env、jobject o、jbyteArray dataToSegment); Java側で
、それはような単純なものです:
今byte[] arg = getRandomByteArray();
Object[] retVal = x.method(arg);
、私は少しトリッキーなことJNIの一部を見つけることです。私はオブジェクトの配列を作成しようとしています。それぞれの配列はバイト配列です。これは、JNIが限られた数のJavaタイプしか定義していないためです。 jbyteArray型とjobjectArray型がありますが、jarrayOfByteArrays型はありません。
だから私は、各オブジェクトが新しいバイト[1024]のように初期化され、オブジェクトの私の配列を作成します。
jbyteArray tmp = (jbyteArray) env->GetObjectArrayElement(retVal, i);
env->SetByteArrayRegion(tmp, 0, size, (jbyte*) sourceBuffer);
env->SetObjectArrayElement(retVal, i, (jobject) tmp); // <--- Questionable line
:ような何かをやって、私は、この配列内のすべてのインデックスを反復
jobjectArray retVal = env->NewObjectArray(numSegs, env->FindClass("[Ljava/lang/Object;"), env->NewByteArray(1024));
など、すべてがうまく機能します。しかし、各バイト配列を可変長にしたい場合はどうすればよいですか?つまり、バイト配列の配列を「ギザギザ」にしたいのです。 NewObjectArray()の最後のパラメータとして初期値として渡すものは何ですか? jobjectArrayの作成時に初期化を防ぐために初期値として0を渡してみましたが、新しいjbyteArrayオブジェクトをSetObjectArrayElement()に渡すように割り当てていましたが、SetObjectArrayElementを呼び出そうとするたびにArrayStoreExceptionをスローしてしまいました。実際、GetObjectArrayElement()の代わりにtmpオブジェクトに新しいjbyteArrayを割り当てても、SetObjectArrayElement()が呼び出されたときに同じ例外がスローされます。最後のコード行が問題になる理由はありますか? jbyteArrayをパラメータとしてSetObjectArrayElement()を呼び出すことはできませんか?
さらに調査すると、「疑問のある行」は何もしていないようです。私がコメントアウトすると、tmpに加えられたすべての変更がretValに反映されます。これはSetByteArrayRegionの呼び出しがcopyではなくjobjectArrayの "中"のバイト配列を扱っているからです。すべての行(むしろすべての一次元のバイト配列)が同じ長さであれば、それで十分です。しかし、彼らはそうではありません。このオブジェクト配列の行の1つに新しいバイト配列を割り当てるにはどうすればよいですか?
TL; DR: JNIではjbyteArraysのjobjectArrayがあります。 jbyteArraysの1つを、NewByteArrayで作成した新しいものに置き換えるにはどうすればよいですか?ヒント:env-> SetObjectArrayElement(retVal、i、(jobject)env-> NewByteArray(size)); //動作しません。
ありがとうございますが、残念ながら私はここでJNIに固執しています。 –
@SzymonSmakolskiはJNIコードからNewDirectByteBufferを使用してバッファを割り当てます。 – Eugene
私の[限られた]理解に基づいて、NewDirectByteBufferはネイティブ側で割り当てられたメモリで動作します。私は、JVMがObject []に詰めることができるたくさんのJava byte []オブジェクトを割り当てるようにしています。あなたが提案するアプローチでは、JVMではなくC++の新しい演算子を使ってバイト配列のそれぞれを割り当てる必要があります。私はむしろJVMが実際にJava側で終わるすべてのデータの割り当てを処理させるでしょう。 –