Передача двухбайтового (WCHAR) представляет в виде строки от C++ до Java через JNI

1123 Это очень близко. Есть несколько проблем:

  • Вам нужен базовый случай. Поскольку n может быть нулем, & epsilon; (пустая строка) на языке. Так что это должно сказать вам, с чего начать.

  • Вы, кажется, думаете, что есть больше b с, чем a с. Но число b с ( n ) меньше или равно числу a с ( м ). Не может быть больше b с. Вместо добавления одного или двух b для каждого a, вам нужно добавить один или два a для каждого b. (Но см. Ниже.)

  • Вы обрабатываете только те случаи, когда дополнительный a сопряжен с одним или двумя b с, которые, как упоминалось выше, должны быть обращены так дополнительный b в паре с некоторыми a с. Но в описании языка говорится m & le; 3 * n *, а не m & le; 2 * n *; дополнительный b может быть в паре с тремя a с.

7
задан Herms 15 May 2009 в 19:27
поделиться

2 ответа

Этот ответ предполагает, что порядок байтов WCHARS не гарантируется ...

Поскольку вы работаете в Windows, вы можете попробовать WideCharToMultiByte для преобразования WCHAR в UTF-8, а затем используйте существующий код JNI.

Будьте осторожны при использовании WideCharToMultiByte из-за возможности переполнения буфера в параметре lpMultiByteStr . Чтобы обойти это, вы должны вызвать функцию дважды, сначала с lpMultiByteStr , установленным на NULL , и cbMultiByte , установленным на ноль - это вернет длину требуемого буфер lpMultiByteStr без попытки записи в него. Когда у вас есть длина, вы можете выделить буфер необходимого размера и снова вызвать функцию.

Пример кода:

int utf8_length;

wchar_t* utf16 = ...;

utf8_length = WideCharToMultiByte(
  CP_UTF8,           // Convert to UTF-8
  0,                 // No special character conversions required 
                     // (UTF-16 and UTF-8 support the same characters)
  utf16,             // UTF-16 string to convert
  -1,                // utf16 is NULL terminated (if not, use length)
  NULL,              // Determining correct output buffer size
  0,                 // Determining correct output buffer size
  NULL,              // Must be NULL for CP_UTF8
  NULL);             // Must be NULL for CP_UTF8

if (utf8_length == 0) {
  // Error - call GetLastError for details
}

char* utf8 = ...; // Allocate space for UTF-8 string

utf8_length = WideCharToMultiByte(
  CP_UTF8,           // Convert to UTF-8
  0,                 // No special character conversions required 
                     // (UTF-16 and UTF-8 support the same characters)
  utf16,             // UTF-16 string to convert
  -1,                // utf16 is NULL terminated (if not, use length)
  utf8,              // UTF-8 output buffer
  utf8_length,       // UTF-8 output buffer size
  NULL,              // Must be NULL for CP_UTF8
  NULL);             // Must be NULL for CP_UTF8

if (utf8_length == 0) {
  // Error - call GetLastError for details
}
7
ответ дан 7 December 2019 в 03:20
поделиться

Я нашел небольшой вопрос о метка порядка байтов. Также из этого FAQ:

UTF-16 и UTF-32 используют кодовые блоки длиной два и четыре байта соответственно. Для этих UTF есть три разновидности: BE, LE и немаркированные. Форма BE использует сериализацию байтов с прямым порядком байтов (сначала наиболее значимый байт), форма LE использует сериализацию байтов с прямым порядком байтов (сначала наименее значимый байт), а в немаркированной форме по умолчанию используется сериализация байтов с прямым порядком байтов, но может включать порядок байтов отметьте в начале, чтобы указать фактическую используемую сериализацию байтов.

Я предполагаю, что на стороне Java UTF-16 попытается найти эту спецификацию и правильно обработать кодировку. Мы все знаем, насколько опасными могут быть предположения ...

Изменить на основании комментария:

Microsoft использует UTF16 с прямым порядком байтов. Java UTF-16 пытается интерпретировать спецификацию. При отсутствии спецификации по умолчанию используется UTF-16BE. Варианты BE и LE игнорируют спецификацию.

2
ответ дан 7 December 2019 в 03:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: