c - JNI/C 库 : passing byte ptr

标签 c android java-native-interface

我的 C 库中有一个 unsigned char*,我正在调用一个 JNI 导出的函数,该函数需要使用此数据设置一个 java 对象,最好是在 byte[] 中

但是这个函数会被调用的很频繁,而且要拷贝的数据也挺多的。

是否可以使用 ByteBuffer 并将该 ByteBuffer 的指针分配给我的 unsigned char*?还是反过来才有效?

我什至可以在不复制数据的情况下执行此操作吗?访问它的最佳方式是什么?

unsigned char* 中数据的大小是已知的。

最佳答案

考虑到您提供的少量信息,这是一个可能的解决方案。

在 Java 方面,您将:

package com.stackoverflow;

public class JNIQuestion
{
  static native void fillByteArray(byte[] buffer);
}

在 C 端,您将拥有:

JNIEXPORT void JNICALL Java_com_stackoverflow_JNIQuestion_fillByteArray(JNIEnv* env, jbyteArray array)
{
  jboolean isCopy;
  jbyte* buffer = (*env)->GetByteArrayElements(env, array, &isCopy);
  jsize length = (*env)->GetArrayLength(env, array);
  jsize i;

  // do something with the buffer here, replace with something meaningful
  // PAY ATTENTION TO BUFFER OVERFLOW, DO NOT WRITE BEYOND BUFFER LENGTH
  for (i = 0; i < length; ++i)
    buffer[i] = i;

  // here it is important to use 0 so that JNI takes care of copying
  // the data back to the Java side in case GetByteArrayElements returned a copy
  (*env)->ReleaseByteArrayElements(env, buffer, 0);
}

使用直接的 ByteBuffer (ByteBuffer.allocateDirect()) 也是一个可能的解决方案。但是,当我需要从 Java 端以非常精确的缓冲区偏移量填充数据时,我只使用直接的 ByteBuffer

关于性能,使用 byte[] 的解决方案应该令人满意,因为 JVM 很可能在调用 GetByteArrayElements() 时固定字节数组而不是复制它。

一般来说,您会希望尽量减少 JNI 调用的次数,这意味着从 C 端访问对象字段或从 C 端分配 Java 将对性能产生影响。

无论如何,先分析,再优化。

PS:我没有尝试编译代码,可能有错别字。引用JNI GuideJNI Tutorial .

关于c - JNI/C 库 : passing byte ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1848886/

相关文章:

c - 二叉树,IsMaxTree

android - 将 flutter CameraImage 转换为文件

c - 打印两个给定字符之间的数组

c - 一个极其特殊的编译器问题

c - 从 C 中的命令参数中读取值

android - 如何获取每个 Kotlin 的当前索引

android - 将 infoWindow 放置在远离重叠多段线的位置

java-native-interface - JPype : fatal error: 'jni.h' file not found

android - 如何在 Android 应用程序中使用 JNI 创建消息队列

java - JNI Hello World 不满意的链接错误