gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 17:46:27 25 4
gpt4 key购买 nike

我正在使用 JNI 编写与 C 库的绑定(bind)。我需要从 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());

然后我将其传递给我的 native 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 语言编写其他内容吗?

最佳答案

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

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

关于java - 将 ByteBuffer 传递给 jni,以便 C 代码在其内存地址中执行写操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60860076/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com