Java и C представляют символьный байт UTF одинаково? - PullRequest
0 голосов
/ 17 октября 2018

Я передаю массив байтов из Java в C, я думаю, что Java и C представляют символьные байты UTF одинаково.

Могу ли я просто сделать это:

jbyte *bytePtr = (*env)->GetByteArrayElements(env, javaByteArray, NULL);

// javaByteArray has java bytes for the UTF chars: 'A', 'B', 'C'

unsigned char *bytePtrC = (unsigned char *) bytePtr;

printf("%c %c %c \n", bytePtrC, bytePtrC+1, bytePtrC+2);

// will this print A B C ?

1 Ответ

0 голосов
/ 17 октября 2018

Нет.

Двоичные байтовые массивы, представляющие данные в виде двух шорт, будут идентичны.

Текст - это еще одиниметь значение.Java имеет дизайн text (String, char) в Unicode, а char является двухбайтовым значением UTF-16.Всегда есть преобразование из byte[] в String с некоторой кодировкой тех байтов, которые будут использоваться.

Итак, в java есть:

byte[] bytes = string.getBytes(StandardCharsets.UTF_8);

Это почти что Cмассив, но для этих различий:

  • bytes.length в качестве поля
  • C имеет дополнительный завершающий нулевой символ: '\0'
  • строка Java может содержатьнуль чар;некоторые классы ( DataOutputStream.writeUTF8 ) будут также кодировать его в многобайтовой последовательности для совместимости со строками Си.Это называется модифицированный UTF-8 .

Но реальной проблемы нет.Только убедитесь, что:

  • Используйте String.getBytes(StandardCharsets.UTF_8) вместо String.getBytes().
  • Используйте new String(bytes, StandardCharsets.UTF_8) вместо new String(bytes).
  • Никогда не используйте String и charдля двоичных данных, как можно было бы использовать C unsigned char*.Он будет использовать вдвое больше памяти, медленное преобразование туда-сюда, которое может повредить данные.
  • Относительно двоичных данных (ByteBuffer.order): short, int, long и так далее с прямым порядком байтов в java.

В качестве последних версий используется кодировка платформы по умолчанию, которая не является переносимой.

...