Как отправить Java ByteBuffer на C, используя JNI?

2

Во-первых, я хочу сказать, что старые ответы не работают (например, функция GetDirectBufferAddress в нижеприведенных ответах требует один параметр сейчас) на данный момент, как здесь:

JNI - собственный метод с параметром ByteBuffer

и здесь,

как писать и читать из bytebuffer, переходя от java в jni

Было бы лучше, если кто-то поможет..

Таким образом, я не могу правильно отправить мой ByteBuffer, который некоторые элементы заполнили, на C из Java, используя JNI, и я не могу вернуть элементы ByteBuffer снова на C

Мое собственное отклонение функции:

public native int myfunc(ByteBuffer pkt);

Распределение для него

private ByteBuffer pkt = ByteBuffer.allocate(1000);

Я называю это следующим образом:

System.out.println(myfunc(pkt));  // Doesn't works, throws exception
pkt.position(0);
System.out.println(pkt.get()); // works, when I do comment line above .println

И мои коды C как показано ниже:

JNIEXPORT jint JNICALL Java_xxx_myfunc(JNIEnv *, jobject, jobject); // header


JNIEXPORT jint JNICALL Java_xxx_myfunc(JNIEnv *env, jobject obj, jobject pkt) // function
{
  jbyte *buff = (jbyte *) env->GetDirectBufferAddress(pkt);
  // buff[0] = 0; I've also tried in this way
  return buff[0];
  //return 1; if I return 1, it returns correctly
}

когда я запускаю программу java, она выдает исключение. Как я могу вернуть свои заполненные значения ByteBuffer из C?

РЕДАКТИРОВАТЬ

A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x719c16b8, pid=1096, tid=1900
  • 0
    Вы можете опубликовать трассировку стека?
  • 0
    @Emax Я использую другой компьютер для кодирования, но отредактировал вопрос как начало трассировки
Показать ещё 3 комментария
Теги:
jni
native
bytebuffer

2 ответа

4
Лучший ответ

Чтобы использовать GetDirectBufferAddress() вы должны гарантировать, что pkt является прямым (вы можете проверить это с помощью isDirect()). ByteBuffer.allocateDirect() способом получения такого объекта является ByteBuffer.allocateDirect(). Прямой ByteBuffer можно также создать из C++.

Разница между прямым и косвенным ByteBuffer четко объясняется в Java- документе.

Обновление. Я вижу ваше обновление. Нет, ByteBuffer.allocate(1000) не создает DirectByteBuffer.

Как правильно заметил @Tom Blodget, спецификация JNI явно говорит, что GetDirectBufferAddress() может возвращать NULL. Это работает в обоих направлениях: сам вызов не должен вылетать, если pkt является непрямым ByteBuffer, но вы должны проверить результат, даже если вы уверены, что pkt является DirectByteBuffer.

  • 1
    Выполнение GetDirectBufferAddress() «C» проверки результата GetDirectBufferAddress() для NULL (согласно документации ) охватит больше случаев, чем isDirect() .
  • 0
    @TomBlodget «C» не должен проверять NULL или isDirect() , это обязанность пользовательской функции предоставить правильный аргумент (конечно, функция должна явно задавать этот тип аргумента в doc);)
0

Вы не можете использовать GetDirectBufferAddress() за исключением прямого байтового буфера. У вас нет прямого байтового буфера.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню