Java использует модифицированную версию UTF-8. Вот цитата из документации Java:
Модифицированный UTF-8 не нов для платформы Java, но это что-то
что разработчики приложений должны быть более осведомлены при конвертации
текст, который может содержать дополнительные символы в и из UTF-8.
Главное помнить, что некоторые интерфейсы J2SE используют
кодировка, похожая на UTF-8, но несовместимая с ней. это
кодирование в прошлом иногда называлось «модифицированный Java UTF-8»
или (неправильно) просто "UTF-8". Для J2SE 5.0 документация
обновляется, чтобы единообразно назвать его «измененным UTF-8».
Несовместимость между модифицированным UTF-8 и стандартным стеблем UTF-8.
из двух отличий. Во-первых, модифицированный UTF-8 представляет символ
U + 0000 в качестве двухбайтовой последовательности 0xC0 0x80, тогда как стандарт UTF-8 использует
однобайтовое значение 0x0. Во-вторых, модифицированный UTF-8 представляет
дополнительные символы путем раздельного кодирования двух суррогатных кодов
единицы их представления UTF-16. Каждый из суррогатных кодовых единиц
представлен тремя байтами, всего шесть байтов. стандарт
UTF-8, с другой стороны, использует одну четырехбайтовую последовательность для
полный характер.
Модифицированный UTF-8 используется виртуальной машиной Java и интерфейсами
прикрепленный к нему (такой как Java Native Interface, различные инструменты
интерфейсы, или файлы классов Java), в java.io.DataInput и
Интерфейсы и классы DataOutput, реализующие или использующие их, и для
сериализации. Собственный интерфейс Java предоставляет процедуры, которые
конвертировать в и из модифицированного UTF-8. Стандарт UTF-8, с другой стороны,
поддерживается классом String, java.io.InputStreamReader и
Классы OutputStreamWriter, средства java.nio.charset и многие другие
API-интерфейсы, расположенные поверх них.
Поскольку модифицированный UTF-8 несовместим со стандартом UTF-8, он
важно не использовать один, где другой нужен. Модифицированная банка UTF-8
использоваться только с интерфейсами Java, описанными выше. Во всех остальных
случаи, в частности, для потоков данных, которые могут приходить или могут быть
интерпретируется программным обеспечением, которое не основано на платформе Java,
должен использоваться стандарт UTF-8. Процедуры нативного интерфейса Java, которые
Преобразование в и из модифицированных UTF-8 не может использоваться, когда стандарт UTF-8
требуется.
Последовательность байтов c2 6c 61 6e 20 4a 6f 6e 65 7e
недопустима в соответствии со стандартом UTF-8. В cp1252 той же самой последовательностью байтов будет строка Âlan Jone~
(обратите внимание Â
вместо À
).
В соответствии со стандартом UTF-8 строка Àlan Jone~
будет представлять собой последовательность байтов c3 80 6c 61 6e 20 4a 6f 6e 65 7e
(уведомление c3 80 6c
вместо c2 6c
).
Все строки Java изначально имеют формат UTF-16, поэтому вам не нужно извлекать строку как UTF-8. Используйте GetStringChars()
, чтобы получить оригинальные символы в кодировке UTF-16 и передать их как есть WideCharToMultiByte()
, указав 1252
в качестве кодовой страницы (обратите внимание, в вашем примере вы используете str
для обоих входных буферов UTF-16 и выходной буфер cp1252 - не путайте ваши переменные!), например:
const jchar *str = jEnv->GetStringChars(jArg2,0);
char *cp1252 = NULL;
int len = WideCharToMultiByte(1252, 0, (LPCWSTR)str, jEnv->GetStringLength(jArg2), NULL, 0, 0, 0);
if (len > 0)
{
cp1252 = new char[len + 1];
WideCharToMultiByte(1252, 0, (LPCWSTR)str, jEnv->GetStringLength(jArg2), cp1252, len, 0, 0);
cp1252[len] = 0;
}