2012-04-30 6 views
1

Android 2.x以降でFloatBuffer.put()メソッドがhereのように非効率的に実装されているため、FloatBuffer.put()のJni置換メソッドを作成しています。しかし、position()とput()でできるように、src floatの配列をdst floatbufferの指定されたオフセットに配置できるようにしたい。これを念頭において、私はこのJNIメソッドを実装しました。JNIメソッドのヘルプ。 Memcpy with destination offset

JNIEXPORT void JNICALL Java_com_voidseer_voidengine_mesh_Vertices_PutFloatsJni 
(JNIEnv *env, jclass, jfloatArray src, jobject dst, jint numFloats, jint dstOffset) 
{ 
     float* pDst = (float*)env->GetDirectBufferAddress(dst); 
     float* pSrc = (float*)env->GetPrimitiveArrayCritical(src, 0); 

     memcpy(pDst + (dstOffset << 2), pSrc, numFloats << 2); 

     env->ReleasePrimitiveArrayCritical(src, pSrc, 0); 
} 

しかし、何かが間違っているようです。私のゲームエンジンは、私のエンティティを描く必要はありません。誰かが間違った点を見つけることができますか?

おかげ

EDIT:

はちょうどそれは、このコードで動作するようになりました。

JNIEXPORT void JNICALL Java_com_voidseer_voidengine_mesh_Vertices_PutFloatsJni 
(JNIEnv *env, jclass, jfloatArray src, jobject dst, jint numFloats, jint dstOffset) 
{ 
     float* pDst = (float*)env->GetDirectBufferAddress(dst); 
     float* pSrc = (float*)env->GetPrimitiveArrayCritical(src, 0); 

     memcpy(&pDst[dstOffset], pSrc, numFloats << 2); 

     env->ReleasePrimitiveArrayCritical(src, pSrc, 0); 
} 
+0

うれしいことに聞こえます。できるだけ作業コードを回答として掲示してください。 – MByD

+0

クール、私はそれを見て...はいかなりかわいい。 JavaのFloat.SIZE静的変数によると、Sizeは4バイトなので、4バイトにする必要があります。また、sizeof(float)を返すだけで4バイトも返すJNIメソッドを作成しました。 memcpyサイズの引数の上のメソッドをsizeof(float)* numFloatsに変更しました。しかし、その部分に影響はありません。 –

+1

私は "&pDst [dstOffset]"は "pDst + dstOffset"と同等であると思います。 C/C++はポインタ演算を使用します。 – Deucalion

答えて

0

このコードで動作するようになりました。

JNIEXPORT void JNICALL Java_com_voidseer_voidengine_mesh_Vertices_PutFloatsJni 
(JNIEnv *env, jclass, jfloatArray src, jobject dst, jint numFloats, jint dstOffset) 
{ 
     float* pDst = (float*)env->GetDirectBufferAddress(dst); 
     float* pSrc = (float*)env->GetPrimitiveArrayCritical(src, 0); 

     //memcpy(pDst + (dstOffset << 2), pSrc, numFloats << 2); 
     memcpy(&pDst[dstOffset], pSrc, sizeof(float) * numFloats); 

     env->ReleasePrimitiveArrayCritical(src, pSrc, 0); 
} 
0
memcpy(pDst + (dstOffset << 2), pSrc, numFloats << 2); 

最初<< 2が正しくありません。それを除く。 Cコンパイラは、sizeof * pDstに基づいてインクリメントを自動的に調整します。

EDIT:2番目のシフトは* sizeof floatである必要があります。

あなたがリンクしている記事の有効性と非動作コードのベンチマークはかなり疑わしいです。

+0

まあ、最初にAndroidプログラミングの本といくつかのAndroid開発者グループの問題について聞いたことがあります。だから私はそれが安全な側にいる方が良いと思います。さらに、JNIとNDKについて学びます。] –

+0

@MichaelWojcik私の主張は、コードがうまくいかなかったので、それから派生したベンチマークは役に立たないということです。 – EJP