Есть ли способ получить прямой указатель на массив Java через JNI? - PullRequest
4 голосов
/ 26 сентября 2011

Мне нужно получить указатель, содержащий прямой адрес памяти массива Java, через JNI, не вызывая какое-либо копирование (т. Е. Прямой доступ).

GetArrayElements возвращает указатель на скопированный массив - Iнеобходимо иметь возможность изменять int [] на уровне Java напрямую с собственного уровня.

Приведение из jintArray к int* возвращает адрес памяти успешно, но я не уверен, что это особенно стабильно ...?

Я могу здесь что-нибудь сделать? ...

Ответы [ 3 ]

5 голосов
/ 26 сентября 2011

Вы можете использовать IntBuffer, используя прямую память (с собственным порядком байтов).В JNI вы можете использовать адрес в качестве указателя.В Java вы должны использовать get () и put ().

3 голосов
/ 26 сентября 2011

Может быть.Есть методы, которые вы можете вызвать, которые могут дать вам прямой указатель на память Java, но это зависит от возможностей JVM.

С http://java.sun.com/docs/books/jni/html/objtypes.html#4099:

JNI поддерживает семейство функций Get / ReleaseArrayElements (включая, например, Get / ReleaseIntArrayElements), которые позволяют нативному коду получать прямой указатель на элементы примитивных массивов.Поскольку базовый сборщик мусора может не поддерживать закрепление, виртуальная машина может возвращать указатель на копию исходного примитивного массива.

Обратите внимание, что вам нужно освободить указатель, когда вы закончите с ним.

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

В JDK 1.3 были добавлены функции Get / ReleasePrimtiveArrayCritical () для получения прямого указателя, даже если JVM делаетне поддерживает закрепление.

"These restrictions make it more likely that the native code will 
obtain an uncopied version of the array, even if the VM does not 
support pinning. For example, a VM may temporarily disable garbage 
collection when the native code is holding a pointer to an 
array obtained via GetPrimitiveArrayCritical."

Однако ожидается, что вы отпустите указатель как можно скорее, и есть ограничения на ваши взаимодействия с JVM.

Альтернатива, если вы часто, но редковзаимодействия с большим массивом, это получить только небольшие области в массиве, с функциями GetArrayRegion () .

0 голосов
/ 10 сентября 2014

Другим способом является получение его адреса и установка одного указателя на него с помощью метода GetDirectBufferAddress .Вы можете найти дополнительную информацию по ссылке:

double * cArr = (double *)((char *)env->GetDirectBufferAddress(inpObject));

Пример GetDirectBufferAddress для сложного объекта

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