【问题标题】:NDK: Does GetByteArrayElements copy data from Java to C++? [closed]NDK:GetByteArrayElements 是否将数据从 Java 复制到 C++? [关闭]
【发布时间】:2014-02-11 01:32:24
【问题描述】:

我已阅读有关 GetByteArrayElements 的链接: 常见问题解答:如何与本机代码共享原始数据? http://developer.android.com/training/articles/perf-jni.html

  1. 它表示 GetByteArrayElements 将返回一个指向 Dalvik 堆中原始数据的实际指针。所以我可以在 C++ 中操作原始源代码并加快进程,对吗?

  2. 那么,ReleaseByteArrayElements 也不会复制数据吗?还是因为 GetByteArrayElements 返回一个指针,而我什至不需要在处理数据后释放它,就像使用 GetDirectBufferAddress for FloatBuffer 一样?

  3. 如果不需要将任何数据从 Java 复制到 C++,是否可以通过 GetByteArrayElements 传入和操作浮点数组?请回复NDK: Passing Jfloat array from Java to C++ via GetByteArrayElements?

【问题讨论】:

  • 您可以考虑验证答案,如果它确实回答了您的问题...

标签: java android c++ c android-ndk


【解决方案1】:
  1. Get<Primitive>ArrayElements 可能会也可能不会复制它认为合适的数据。 isCopy 输出参数将告诉您它是否已被复制。如果没有复制数据,那么您已经直接在 Dalvik 堆中获得了指向数据的指针。阅读更多here

  2. 无论是否创建了副本,您始终需要调用相应的Release<Primitive>ArrayElements。将数据复制回 VM 阵列并不是唯一可能需要完成的清理工作,尽管(根据已链接的 JNI 文档)在调用 Release... 之前可以在 Java 端看到更改是可行的(如果数据没有被复制)。

  3. 我不相信 VM 将允许您进行必要的转换来完成您的想法。正如我所看到的,无论哪种方式,您都需要将字节数组转换为浮点数或将浮点数转换为 Java 中的字节数组,这无法通过类型转换来完成。数据将在某个时候被复制。

编辑:

使用ByteBuffer.allocateDirectByteBuffer.asFloatBufferGetDirectBufferAddress 可以实现您想要做的事情。在 Java 中,您可以使用 FloatBuffer 将数据解释为浮点数,并且使用 GetDirectBufferAddress 可以直接在本机代码中使用该数组。我发布了您其他问题的答案作为进一步的解释。

【讨论】:

  • 附加说明:如果您使用直接的ByteBuffer(如果性能有任何问题,则应该使用),不要依赖array() method。尽管它在许多情况下看起来都很完美,但它是一种可选的 API 方法,例如,在至少 API 23 的 Android 设备上不可用(并且可能仍然不可用)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
  • 2013-04-30
相关资源
最近更新 更多