Библиотека JNI / C: передаваемый байт ptr - PullRequest
3 голосов
/ 04 декабря 2009

У меня есть unsigned char* в моей библиотеке C, и я вызываю JNI-экспортированную функцию, которая должна установить объект Java с этими данными, предпочтительно в byte[].

Но эта функция будет вызываться очень часто, и ее будет скопировано довольно много.

Можно ли использовать ByteBuffer и назначить указатель этого ByteBuffer моему unsigned char*? Или это работает только наоборот?

Могу ли я сделать это без копирования данных? Как лучше всего получить к нему доступ?

Размер данных в unsigned char* известен.

1 Ответ

4 голосов
/ 04 декабря 2009

Вот возможное решение, учитывая небольшую информацию, которую вы предоставили.

На стороне 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()) также является возможным решением. Однако я использую прямой ByteBuffer, только когда мне нужно заполнить данные со стороны Java очень точными смещениями в буфере.

Что касается производительности, решение, использующее byte[], должно быть удовлетворительным, поскольку JVM, скорее всего, закрепит байтовый массив вместо его копирования при вызове GetByteArrayElements().

Вообще говоря, вам нужно минимизировать количество вызовов JNI, что подразумевает, что доступ к полям объекта со стороны C или выделение Java со стороны C будут влиять на производительность.

В любом случае, сначала профиль, затем оптимизировать.

PS: я не пытался скомпилировать код, могут быть опечатки. См. Руководство по JNI и Учебное пособие по JNI .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...