我有一个C函数,如下所示:
int getInfo(int index, int type, void *pValue, int valueLen);
pValue
是用于保存信息值的缓冲区的地址。但是,缓冲区必须已经由调用方预先分配。
由于我相当确定我正在处理小数据,因此我将在Java托管代码中执行以下操作...
public native int callGetInfo(int index, int type, byte[] value);
...然后传递一个固定大小的字节数组,如下所示:
byte[] buf = new byte[1024];
callGetInfo(idx, t, buf);
原因是因为我读到小数据,在性能方面,使用字节数组比ByteBuffer
好。
我自动生成的JNI标头如下:
JNIEXPORT jint JNICALL Java_com_testing_jni_Tester_callGetInfo (JNIEnv *, jobject, jint, jint, jbyteArray);
在我的桥接函数中,我想将pValue
函数返回的getInfo
的值(可能是任何类型)转换为jbyteArray
,以便我可以将其返回给Java调用者。我该如何实现?
答案 0 :(得分:1)
解决方案将类似于
JNIEXPORT jint JNICALL Java_com_testing_jni_Tester_callGetInfo
(JNIEnv *env, jobject obj, jint index, jint type, jbyteArray array)
{
jboolean isCopy;
jsize arrayLength = (*env)->GetArrayLength(env, array);
jbyte* bufferPtr = (*env)->GetByteArrayElements(env, array, &isCopy);
if (! bufferPtr) {
// got exception
return 0;
}
jint rv = getInfo(index, type, bufferPtr, arrayLength);
(*env)->ReleaseByteArrayElements(env, array, bufferPtr, 0);
return rv;
}
还有一个调用GetPrimitiveArrayCritical
和ReleasePrimitiveArrayCritical
可能不可用,因为未知getInfo
的内容-特别是在使用这些功能时,getInfo
函数无法使用执行任何阻塞的系统调用或进行长时间运行的操作。
isCopy
告知是否复制了锁定的数组。如果未复制,则该函数将直接修改实际的Java数组。如果是副本,则现在将1024字节的缓冲区复制到另一个位置,并将在函数末尾复制回去。可能是您不希望发生这种情况...也许您想使用字节缓冲区代替...