将ByteBuffer传递给jni,以便C代码在其内存地址中进行写操作

问题描述 投票:0回答:1

我正在使用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;
  }

这有效。但我有以下问题:

  • 这安全吗?
  • Java中的GC是否在操作过程中不能摆脱它?
  • 我是否还需要c中的其他内容?
java java-native-interface bytebuffer
1个回答
0
投票

[是,这很安全,假设finalize不在[output, output + output_len[范围之外写入,并且您不共享线程之间的字节缓冲区。 (如@Johannes Kuhn所述)

当您使用JVM对象(您的ByteBuffer)调用JNI函数时,调用代码显然具有对其的引用,因此不会被垃圾回收。在本机端,您会收到一个本地引用,该引用仅在JNI调用期间有效,但如果希望对象在调用中存活下来,则可以将其转换为全局引用。

© www.soinside.com 2019 - 2024. All rights reserved.