在Android游戏中将java.nio.IntBuffer传递给C函数
我希望能够在我的Android应用程序中添加一些原生C代码。我有一个IntBuffer,用作OpenGL的glColorPointer方法的参数。这是这样填充/使用的:在Android游戏中将java.nio.IntBuffer传递给C函数,android,java-native-interface,android-ndk,Android,Java Native Interface,Android Ndk,我希望能够在我的Android应用程序中添加一些原生C代码。我有一个IntBuffer,用作OpenGL的glColorPointer方法的参数。这是这样填充/使用的: private IntBuffer mColourBuffer; int[] colours = new int[10 * 4]; // 10 dots, 4 colour components per dot ByteBuffer vbb3 = ByteBuffer.allocateDirect(10 * 4 * 4)
private IntBuffer mColourBuffer;
int[] colours = new int[10 * 4]; // 10 dots, 4 colour components per dot
ByteBuffer vbb3 = ByteBuffer.allocateDirect(10 * 4 * 4);
vbb3.order(ByteOrder.nativeOrder());
mColourBuffer = vbb3.asIntBuffer();
mColourBuffer.put(colours);
mColourBuffer.position(0);
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColourBuffer);
public native void mymethod(IntBuffer intbuf, int n);
mymethod(mColourBuffer , n);
void Java_com_a_b_c_JNIfastPutf(JNIEnv* env, jobject thiz, jobject jo, jfloatArray jfa, int n)
{
float* pDst = (float*) (*env)->GetDirectBufferAddress(env, jo);
float* pSrc = (float*) (*env)->GetPrimitiveArrayCritical(env, jfa, 0);
memcpy( pDst, pSrc, n );
(*env)->ReleasePrimitiveArrayCritical(env, jfa, pSrc, 0);
}
我想对这个缓冲区进行更改,但它在Java中太慢了,所以我想用本机代码进行更改。我一直在寻找一个简单的例子,但我找不到任何我能理解的,或有效的。我看到的很多文档都谈到传递元素,但我想要的肯定是一个指针。传递指针并对其指向的内存进行操作应该是非常高效的;在Java和C之间传递内存负载会扼杀任何可能通过从C操作内存而实现的速度提升
到目前为止,我已经想到了这个:
void Java_com_poldie_myTouch2_myclass_mymethod( JNIEnv* env, jobject thiz, jintArray arr, int n )
{
jint *c_array;
c_array = (*env)->GetIntArrayElements(env, arr, NULL);
(*env)->ReleaseIntArrayElements(env, arr, c_array, 0);
return;
}
我可以这样称呼它:
private IntBuffer mColourBuffer;
int[] colours = new int[10 * 4]; // 10 dots, 4 colour components per dot
ByteBuffer vbb3 = ByteBuffer.allocateDirect(10 * 4 * 4);
vbb3.order(ByteOrder.nativeOrder());
mColourBuffer = vbb3.asIntBuffer();
mColourBuffer.put(colours);
mColourBuffer.position(0);
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColourBuffer);
public native void mymethod(IntBuffer intbuf, int n);
mymethod(mColourBuffer , n);
void Java_com_a_b_c_JNIfastPutf(JNIEnv* env, jobject thiz, jobject jo, jfloatArray jfa, int n)
{
float* pDst = (float*) (*env)->GetDirectBufferAddress(env, jo);
float* pSrc = (float*) (*env)->GetPrimitiveArrayCritical(env, jfa, 0);
memcpy( pDst, pSrc, n );
(*env)->ReleasePrimitiveArrayCritical(env, jfa, pSrc, 0);
}
它至少运行并似乎执行调用,但任何对c_数组(作为解引用指针或数组)进行操作的尝试都会导致程序立即退出
我走对了吗?我可以将指向mColourBuffer后面内存的指针传递给我的C代码,并在返回Java代码时对其进行操作吗?回答我自己的问题,答案似乎是获取顶点数组(使用Java操作每个帧)并将其写入直接缓冲区 在上面的示例中,我希望以某种方式使用本地数组“colors”中的任何内容填充每个帧的直接缓冲区mColourBuffer。结果你想要的是:
JNIfastPutf(mfColourBuffer, colours, nCount);
其中nCount是要复制的字节数。(本机,C)函数JNIfastPutf如下所示:
private IntBuffer mColourBuffer;
int[] colours = new int[10 * 4]; // 10 dots, 4 colour components per dot
ByteBuffer vbb3 = ByteBuffer.allocateDirect(10 * 4 * 4);
vbb3.order(ByteOrder.nativeOrder());
mColourBuffer = vbb3.asIntBuffer();
mColourBuffer.put(colours);
mColourBuffer.position(0);
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColourBuffer);
public native void mymethod(IntBuffer intbuf, int n);
mymethod(mColourBuffer , n);
void Java_com_a_b_c_JNIfastPutf(JNIEnv* env, jobject thiz, jobject jo, jfloatArray jfa, int n)
{
float* pDst = (float*) (*env)->GetDirectBufferAddress(env, jo);
float* pSrc = (float*) (*env)->GetPrimitiveArrayCritical(env, jfa, 0);
memcpy( pDst, pSrc, n );
(*env)->ReleasePrimitiveArrayCritical(env, jfa, pSrc, 0);
}
< >我发现下面的链接非常有用(我的函数是C++的例子的一个稍微修改的C版本):
他们解释说,如果你使用浮动,你真的需要这种方法;使用int应该快得多,尽管我就是从这里开始的,而且在任何情况下,它们的原生代码都比“fast”int版本的速度提高了20->100%,所以似乎没有什么理由不这么做 不同版本的安卓系统的速度各不相同。Dalvik core libs的最新版本具有更好的性能。