jstring к L_TCHAR* формат

Я пытался вызвать функцию C, которая имеет следующую подпись

int changeFoo(L_TCHAR* pszFileSrc){....}

в моем вызове JNI мой метод похож на это:

JNIEXPORT jint JNICALL Java_com_me_L_AFoo(JNIEnv * env, jclass jclass, jstring pSrc)
{
    jint retValue = -100;
    retValue = changeFoo(pSrc);
    return retValue;
}

Я получаю следующую ошибку в Visual Studio.

Ошибка 1 ошибка C2664: 'L_FileConvert': не может преобразовать параметр 1 от 'jstring' до 'L_TCHAR *' c:\Ayusman\Work\MyVCpp\LTExampleDll\LTExampleDll\LTExampleMain.cpp 46 LTExampleDll

Когда я посмотрел на определение L_TCHAR *

вот то, что я вошел в заголовочные файлы (в той последовательности):

typedef TCHAR L_TCHAR;
typedef WCHAR TCHAR,*PTCHAR;
typedef wchar_t WCHAR; //wc, 16 bit UNICODE char

Я работаю над Java, это - приложение JNI, которое я пытаюсь создать. Какое-либо тело может помочь относительно того, как я могу преобразовать это правильно?

1
задан Kredns 1 May 2010 в 02:49
поделиться

1 ответ

Вам придется вручную преобразовывать строку. Вот (исправленный) пример кода:

#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "Foo.h"
#define SURROGATE_MASK 0xD800
#define is_surrogate(c) (((c) & SURROGATE_MASK) == SURROGATE_MASK)

static wchar_t calculate_code_point(wchar_t surrogate_1, wchar_t surrogate_2);

JNIEXPORT void JNICALL
Java_Foo_foo(JNIEnv *env, jobject obj, jstring bar) {
  const jchar *chars = NULL;
  wchar_t *result = NULL;
  size_t len;
  size_t source_pos, result_pos;

  if (bar == NULL) {
    return;
  }

  len = (*env)->GetStringLength(env, bar);
  chars = (*env)->GetStringChars(env, bar, NULL);
  if (chars == NULL) {
    return;
  }

  result = (wchar_t *) malloc(sizeof(wchar_t) * (len + 1));
  source_pos = result_pos = 0;
  while (source_pos < len) {
    wchar_t curr_char = chars[source_pos++];
    if (is_surrogate(curr_char)) {
      wchar_t surrogate_1 = curr_char;
      wchar_t surrogate_2 = chars[source_pos++];
      curr_char = calculate_code_point(surrogate_1, surrogate_2);
    }
    result[result_pos++] = curr_char;
  }
  result[result_pos] = L'\0';

  (*env)->ReleaseStringChars(env, bar, chars);

  printf("%ls\n", result);
  free(result);
}

/**
 * Based on example code from http://unicode.org/faq/utf_bom.hmtl
 */
static wchar_t calculate_code_point(wchar_t high_surrogate, wchar_t low_surrogate) {
  wchar_t x = (high_surrogate & ((1 << 6) - 1)) <<10 | low_surrogate & ((1 << 10) - 1);
  wchar_t w = (high_surrogate >> 6) & ((1 << 5) - 1);
  wchar_t u = w + 1;
  return u << 16 | x;
}

Обратите внимание, что этот код применим, только если вы используете Java 5 или выше и ваш тип данных wchar_t имеет длину четыре байта. Если вы используете Java 1.4 или ниже, или ваш тип данных wchar_t имеет длину два байта, то вам не нужно беспокоиться о суррогатах.

В этом коде также отсутствует базовая проверка ошибок и предполагается, что первый суррогат в паре является суррогатом высшего порядка (что и происходит на моей машине). Вы можете точно определить, какой суррогат является суррогатом высшего порядка, а какой - низшего, по их соответствующим значениям. Суррогат высокого порядка находится между 0xD800 и 0xDBFF, включительно. Суррогат низшего порядка находится между 0xDC00 и 0xDFFF, включительно. Если вы найдете суррогат высокого порядка, который не сопряжен с суррогатом низкого порядка, или суррогат низкого порядка, который не сопряжен с суррогатом высокого порядка, то строка будет закодирована неправильно.

2
ответ дан 3 September 2019 в 00:55
поделиться
Другие вопросы по тегам:

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