java.nio.DirectByteBuffer
делает то, что вы хотите.
Внутренне он использует private long address
для хранения значения указателя. Дах!
Используйте функцию JNI env->NewDirectByteBuffer((void*) data, sizeof(MyNativeStruct))
, чтобы создать DirectByteBuffer на стороне C / C ++ и вернуть его на сторону Java в качестве ByteBuffer. Примечание: Ваша задача - освободить эти данные на родной стороне! В нем отсутствует автоматический очиститель, доступный в стандартном DirectBuffer.
На стороне Java вы можете создать DirectByteBuffer следующим образом:
ByteBuffer directBuff = ByteBuffer.allocateDirect(sizeInBytes);
Думайте, что-то вроде C malloc(sizeInBytes)
. Примечание: Имеет автоматический очиститель, который освобождает память, запрошенную ранее.
Но есть некоторые моменты, которые следует учитывать при использовании DirectByteBuffer:
- Это может быть сборщик мусора (GC), если вы пропустите прямую ссылку на ByteBuffer.
- Вы можете читать / записывать значения в заостренную структуру, но остерегайтесь как смещения, так и размера данных. Компилятор может добавить дополнительные пробелы для заполнения и нарушить ваши предполагаемые внутренние смещения в структуре. Структура с указателями (шаг 4 или 8 байт?) Также озадачивает ваши данные.
- Direct ByteBuffers очень легко передать в качестве параметра для нативных методов, а также вернуть его в качестве возврата.
- Вы должны привести к правильному типу указателя на стороне JNI. Тип по умолчанию, возвращаемый
env->GetDirectBufferAddress(buffer)
, равен void*
.
- Вы не можете изменить значение указателя после его создания.
- Ваша задача освободить память, ранее выделенную для буферов на нативной стороне. Те, которые вы использовали с
env->NewDirectByteBuffer()
.