Ответ 1
IIRC, как java.util.zip
, так и java.nio
просто используйте long
.
Каков правильный способ хранения встроенного указателя внутри объекта Java?
Я мог бы рассматривать указатель как Java int
, если я знаю, что собственные указатели имеют размер = lt; = 32 бит или Java long
, если я знаю, что собственные указатели равны <= 64 бит. Но есть ли лучший или более чистый способ сделать это?
Изменить. Возвращение встроенного указателя из JNI-функции - именно то, что я не хочу делать. Я предпочел бы вернуть объект Java, представляющий собственный ресурс. Однако возвращаемый объект Java должен иметь поле, содержащее указатель, который возвращает меня к исходному вопросу.
Или, альтернативно, есть ли лучший способ для функции JNI вернуть ссылку на собственный ресурс?
IIRC, как java.util.zip
, так и java.nio
просто используйте long
.
Нет хорошего пути. В SWT используется этот код:
int /*long*/ hModule = OS.GetLibraryHandle ();
и есть инструмент, который преобразует код между 32 бит и 64 бит, перемещая комментарий. Уродливый, но он работает. Было бы намного проще, если бы Sun добавил объект "NativePointer" или что-то в этом роде, но они этого не сделали.
java.nio.DirectByteBuffer
делает то, что вы хотите.
Внутри он использует private long address
для хранения значения указателя. Да!
Используйте JNI-функцию env->NewDirectByteBuffer((void*) data, sizeof(MyNativeStruct))
, чтобы создать DirectByteBuffer на стороне C/С++ и вернуть ее на Java-стороне в качестве ByteBuffer. Примечание: Это ваша работа, чтобы освободить эти данные на родной стороне! Он пропускает автоматический очиститель, доступный в стандартном DirectBuffer.
На стороне Java вы можете создать DirectByteBuffer следующим образом:
ByteBuffer directBuff = ByteBuffer.allocateDirect(sizeInBytes);
Подумайте, что это C malloc(sizeInBytes)
. Примечание: У него есть автоматический очиститель, который освобождает запрошенную память.
Но есть несколько вопросов, которые следует учитывать при использовании DirectByteBuffer:
env->GetDirectBufferAddress(buffer)
, равен void*
.env->NewDirectByteBuffer()
.Лучше всего хранить его в байтовом массиве, поскольку нативные указатели не очень похожи на Java-иш. int
и long
лучше зарезервированы для хранения числовых значений.
Я предполагаю, что это указатель, возвращенный из некоторого кода JNI, и мой совет будет просто не делать этого.
В идеале код JNI должен передать вам некоторую логическую ссылку на ресурс, а не фактический указатель?
Что касается вашего вопроса, то ничего не приходит в голову о более чистом способе хранения указателя - если вы знаете, что у вас есть, тогда используйте либо int, либо long или byte [], как требуется.
Вы можете посмотреть, как С# обрабатывает это с помощью типа IntPtr. Создавая свой собственный тип для удерживающих указателей, один и тот же тип может использоваться как 32-разрядный или 64-разрядный, в зависимости от системы, в которой вы находитесь.