Предполагая, что вы ограничиваете себя общедоступными классами и их общедоступными API, у вас есть две относительно эффективные альтернативы для решения проблемы, но их объединяет то, что они полагаются на помещение данных в Java byte[]
.Это не так сложно:
/* error checks omitted for brevity; these are *not* optional */
char *cBytes = /* ... */;
size_t numCBytes = /* ... */;
jbyteArray javaBytes = /* ... */;
jsize numBytes = (*env)->GetArrayLength(env, javaBytes);
jbyte *bytes = (*env)->GetPrimitiveArrayCritical(env, javaBytes, NULL);
/* It is pretty safe to assume that jbyte is a character type, such as signed
char, in any C implementation that supports the JNI at all */
/* Assumes numCBytes <= numBytes; adjust as necessary if that may not be true: */
memcpy(bytes, cBytes, numCBytes);
(*env)->ReleasePrimitiveArrayCritical(env, javaBytes, bytes, 0);
Обратите внимание, что если функция JNI выполняет какой-либо ввод-вывод для получения байтов, она может прочитать их непосредственно в bytes
(в зависимости от собственных требованийне в JNI), но в этом случае вы должны использовать не Critical
версии подпрограмм Get
/ Release
.
С учетом сказанного, ваши две основные альтернативы для получения всех данныхпуть в ByteBuffer
:
, если буфер hasArray()
, затем получить byte[]
для вышеуказанной процедуры с помощью метода буфера array()
.Готово и сделано.
, если буфер не hasArray()
, или если вы не хотите проверять, тогда получите byte[]
, создав его заново и после загрузкис помощью описанной выше процедуры скопируйте содержимое в буфер с помощью метода Bulb put(byte[])
или put(byte[], int, int)
.Очевидно, что это включает дополнительную копию относительно другой альтернативы и использует дополнительный временный объект.
Я не могу рекомендовать использовать конкретный конкретный ByteBuffer
подкласс или полагаться на непубличныйметоды.Возможно, стоит подумать, если бы производительность была высоким приоритетом, но вы, кажется, сказали, что это не так.