gpt4 book ai didi

java - 在 JNI 函数中,当我就地更改从 Java 代码传递的数组时,数组不会修改

转载 作者:行者123 更新时间:2023-12-03 17:41:49 25 4
gpt4 key购买 nike

我正在将一个 int 数组从 Java 传递到 native 方法。然后在 JNI 函数中,我使用 GetIntArrayElements() 创建了一个指向 int 数组的指针,并作为 *isCopy 参数 JNI_FALSE 传递。我认为这不会创建原始数组的副本,我可以就地修改数组。然后我使用 ReleaseIntArrayElements() 并作为模式参数 JNI_ABORT 传递给仅释放缓冲区。但这没有用。

来自 JNI 文档:

  • 模式 0:复制回内容并释放 elems 缓冲区
  • 模式 JNI_COMMIT:复制回内容但不释放 elems 缓冲区
  • 模式 JNI_ABORT:释放缓冲区而不复制可能的更改

当我尝试在 ReleaseIntArrayElements() 中使用模式“0”时效果很好。但我不明白为什么我没有创建原始数组的副本,而模式“0”正在复制内容。

我想 JNI 总是创建原始数组的副本。但是 GetIntArrayElements() 中的 *isCopy 参数失去了意义。那么这到底发生了什么?

这是我的 JNI 函数

extern "C" JNIEXPORT jdouble JNICALL
Java_my_own_package_MainActivity_myFunction(
JNIEnv *env,
jobject /* this */, jintArray tbl) {
jint *tblptr = env->GetIntArrayElements(tbl, JNI_FALSE);
tblptr[0] = 0; //in-place change
env->ReleaseIntArrayElements(tb1, tblptr, JNI_ABORT);
return 0;
}

最佳答案

您误用了 jboolean *isCopy。这是一个在实际调用 env->GetIntArrayElements(tbl, isCopy); 之后应该检查的输出参数。如果它返回 JNI_FALSE 则不进行复制。

这是必要的,因为 GC 可以将元素从一个位置移动到另一个位置不可预测地,您应该始终将更改复制回原始 java 数组。因为你永远不知道实际 java 数组的内存位置。

如果您不希望制作副本,您可能正在寻找该方法的 critical 版本。 JNI 文档是这样说的:

These restrictions make it more likely that the native code > will obtain an uncopied version of the array, even if the VM > does not support pinning

这并不意味着只要您持有临界区,JVM 就会禁用垃圾收集,尽管它很可能会这样做。

Emp.我的:

For example, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical

关于java - 在 JNI 函数中,当我就地更改从 Java 代码传递的数组时,数组不会修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54597057/

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