2016-11-04 4 views
0

Я изучаю JNI в наши дни. Скажем, у меня есть библиотечная функция C/C++, которая принимает int * array как вход (мы предполагаем, что int имеет 4 байта и подписан так же, как и в Java), то есть массив, переданный как указатель. Можно ли передать Java-массив из int в такую ​​функцию через JNI, не делая никакого копирования (Очевидно, мы удаляем часть длины массива Java при этом)? Является ли прямой ByteBuffer единственным жизнеспособным методом для таких действий?Может ли массив Java быть передан функции C/C++, которая принимает массив?

ответ

2

Прямой ByteBuffer был бы одним из способов избежать копирования, как вы упомянули сами.

Если вы передаете массив Java, вам необходимо позвонить Get<Primitive>ArrayElements, который может или не копию (или Get<Primitive>ArrayRegion, но это было бы никакого смысла, так как он всегда копирует).

Существует также GetPrimitiveArrayCritical, который вы можете использовать, если вам нужен только доступ к элементам для «короткого» количества времени, и не нужно выполнять какие-либо другие вызовы JNI перед выпуском элементов. Это «скорее», чем Get<Primitive>ArrayElements, чтобы не копировать.

Пример:

jint len = env->GetArrayLength(myIntArray); 
jint *elements = env->GetPrimitiveArrayCritical(myIntArray, NULL); 

// Use elements... 

env->ReleasePrimitiveArrayCritical(myIntArray, elements, 0); 

См Oracle's JNI documentation.

+0

Итак, в основном прямой ByteBuffer является единственным надежным способом достижения этого? – pythonic

+0

Я так думаю, если только вы не нацеливаете определенную виртуальную машину, которая, как вы знаете, ведет себя определенным образом. – Michael