Передача ByteBuffer в jni для кода C для выполнения операций записи в его адрес памяти - PullRequest
0 голосов
/ 26 марта 2020

Я пишу привязки к библиотеке c, используя JNI. У меня есть следующий метод, который мне нужно вызвать из 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());

, а затем я передаю его своему родному вызову 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;
  }

Это работает. но у меня есть следующие вопросы:

  • Это безопасно?
  • Разве G C в Java не собирается избавляться от него в середине операции?
  • Нужно ли мне что-то еще в c?

1 Ответ

0 голосов
/ 26 марта 2020

Да, это безопасно, при условии, что finalize не записывает вне диапазона [output, output + output_len[, и вы не разделяете байтовые буферы между потоками. (как заметил @Johannes Kuhn)

Когда вы вызываете функцию JNI с объектом JVM (ваш ByteBuffer), вызывающий код явно имеет ссылку на него, поэтому он не будет собирать мусор. На нативной стороне вы получаете локальную ссылку, которая действительна только для продолжительности вызова JNI, но вы можете преобразовать ее в глобальную ссылку, если хотите, чтобы объект пережил вызов.

...