我正在使用JNI将绑定写到c库。我需要从Java调用以下方法
void finalize(uint8_t *out, size_t out_len)
我一直在做什么:
JNIEXPORT jbyteArray JNICALL myjnicall
(JNIEnv *env, jclass classObject, jlong hp, jint output_len)
{
jbyteArray retArray;
uint8_t output[output_len];
finalize(output, output_len);
retArray = (*env)->NewByteArray(env, output_len);
(*env)->SetByteArrayRegion(env, retArray, 0, output_len, (jbyte*)output);
return retArray;
}
这在小输出时也能正常工作。但是该库可提供极大的输出。我想做的是这个:
在Java中,我有一个像这样的字节缓冲区
byteBuff = ByteBuffer.allocateDirect(outputLength);
byteBuff.order(ByteOrder.nativeOrder());
然后我将其传递给我的本地JNI调用:
JNIEXPORT void JNICALL myjnicall
(JNIEnv *env, jclass classObject, jobject byteBuffer, jint output_len)
{
uint8_t *output = (uint8_t*) (*env)->GetDirectBufferAddress(env, byteBuffer);
finalize(output, output_len); //populating the memory space
return;
}
这有效。但我有以下问题:
[是,这很安全,假设finalize
不在[output, output + output_len[
范围之外写入,并且您不共享线程之间的字节缓冲区。 (如@Johannes Kuhn所述)
当您使用JVM对象(您的ByteBuffer)调用JNI函数时,调用代码显然具有对其的引用,因此不会被垃圾回收。在本机端,您会收到一个本地引用,该引用仅在JNI调用期间有效,但如果希望对象在调用中存活下来,则可以将其转换为全局引用。