Как мне конвертировать jstring в wchar_t * - PullRequest
12 голосов
/ 16 сентября 2008

Скажем, на стороне C ++ моя функция принимает переменную типа jstring с именем myString. Я могу преобразовать его в строку ANSI следующим образом:

const char* ansiString = env->GetStringUTFChars(myString, 0);

есть ли способ получить

const wchar_t* unicodeString = ...

Ответы [ 9 ]

13 голосов
/ 01 февраля 2012

Если это кому-нибудь поможет ... Я использовал эту функцию для проекта Android:

std::wstring Java_To_WStr(JNIEnv *env, jstring string)
{
    std::wstring value;

    const jchar *raw = env->GetStringChars(string, 0);
    jsize len = env->GetStringLength(string);
    const jchar *temp = raw;
    while (len > 0)
    {
        value += *(temp++);
        len--;
    }
    env->ReleaseStringChars(string, raw);

    return value;
}

Улучшенное решение может быть (Спасибо за отзыв):

std::wstring Java_To_WStr(JNIEnv *env, jstring string)
{
    std::wstring value;

    const jchar *raw = env->GetStringChars(string, 0);
    jsize len = env->GetStringLength(string);

    value.assign(raw, raw + len);

    env->ReleaseStringChars(string, raw);

    return value;
}
4 голосов
/ 19 февраля 2010

А кто освобождает wsz? Я бы порекомендовал STL!

std::wstring JavaToWSZ(JNIEnv* env, jstring string)
{
    std::wstring value;
    if (string == NULL) {
        return value; // empty string
    }
    const jchar* raw = env->GetStringChars(string, NULL);
    if (raw != NULL) {
        jsize len = env->GetStringLength(string);
        value.assign(raw, len);
        env->ReleaseStringChars(string, raw);
    }
    return value;
}
3 голосов
/ 16 сентября 2008

JNI также имеет функцию GetStringChars (). Тип возвращаемого значения - const jchar *, jchar - 16-битный на win32, поэтому он будет совместим с wchar_t. Не уверен, что это настоящий UTF-16 или что-то еще ...

3 голосов
/ 16 сентября 2008

Переносное и надежное решение - использовать iconv , при этом необходимо понимать, какую кодировку использует ваша система wchar_t (UTF-16 в Windows, UTF-32 во многих системах Unix, например).

Если вы хотите минимизировать свою зависимость от стороннего кода, вы также можете прокрутить свой собственный конвертер UTF-8. Это легко, если конвертировать в UTF-32, несколько сложнее с UTF-16, потому что вам приходится работать и с суррогатными парами. :-P Кроме того, вы должны быть осторожны, чтобы отклонить не самые короткие формы, иначе в некоторых случаях это может вызвать ошибки безопасности.

2 голосов
/ 03 ноября 2009

Я знаю, что об этом спрашивали год назад, но мне не нравятся другие ответы, поэтому я все равно отвечу. Вот как мы это делаем в нашем источнике:

wchar_t * JavaToWSZ(JNIEnv* env, jstring string)
{
    if (string == NULL)
        return NULL;
    int len = env->GetStringLength(string);
    const jchar* raw = env->GetStringChars(string, NULL);
    if (raw == NULL)
        return NULL;

    wchar_t* wsz = new wchar_t[len+1];
    memcpy(wsz, raw, len*2);
    wsz[len] = 0;

    env->ReleaseStringChars(string, raw);

    return wsz;
}

РЕДАКТИРОВАТЬ : Это решение хорошо работает на платформах, где wchar_t составляет 2 байта, некоторые платформы имеют 4 байта wchar_t, в этом случае это решение не будет работать.

0 голосов
/ 10 декабря 2018

Я пытаюсь jstring-> char-> wchar_t

char* js2c(JNIEnv* env, jstring jstr)
{
    char* rtn = NULL;
    jclass clsstring = env->FindClass("java/lang/String");
    jstring strencode = env->NewStringUTF("utf-8");
    jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
    jbyteArray barr = (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
    jsize alen = env->GetArrayLength(barr);
    jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
    if (alen > 0)
    {
        rtn = (char*)malloc(alen + 1);
        memcpy(rtn, ba, alen);
        rtn[alen] = 0;
    }
    env->ReleaseByteArrayElements(barr, ba, 0);
    return rtn;
}

jstring c2js(JNIEnv* env, const char* str) {
    jstring rtn = 0;
    int slen = strlen(str);
    unsigned short * buffer = 0;
    if (slen == 0)
        rtn = (env)->NewStringUTF(str);
    else {
        int length = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str, slen, NULL, 0);
        buffer = (unsigned short *)malloc(length * 2 + 1);
        if (MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length) > 0)
            rtn = (env)->NewString((jchar*)buffer, length);
        free(buffer);
    }
    return rtn;
}



jstring w2js(JNIEnv *env, wchar_t *src)
{
    size_t len = wcslen(src) + 1;
    size_t converted = 0;
    char *dest;
    dest = (char*)malloc(len * sizeof(char));
    wcstombs_s(&converted, dest, len, src, _TRUNCATE);

    jstring dst = c2js(env, dest);
    return dst;
}

wchar_t *js2w(JNIEnv *env, jstring src) {

    char *dest = js2c(env, src);
    size_t len = strlen(dest) + 1;
    size_t converted = 0;
    wchar_t *dst;
    dst = (wchar_t*)malloc(len * sizeof(wchar_t));
    mbstowcs_s(&converted, dst, len, dest, _TRUNCATE);
    return dst;
}
0 голосов
/ 11 ноября 2010

Скорее просто. Но не забудьте освободить память с помощью ReleaseStringChars

JNIEXPORT jboolean JNICALL Java_TestClass_test(JNIEnv * env, jobject, jstring string)
{
    const wchar_t * utf16 = (wchar_t *)env->GetStringChars(string, NULL);
    ...
    env->ReleaseStringChars(string, utf16);
}
0 голосов
/ 30 апреля 2009

Просто используйте env-> GetStringChars (myString, 0); Java передает Unicode по своей природе

0 голосов
/ 16 сентября 2008

Если мы не заинтересованы в кроссплатформенности, в окнах вы можете использовать функцию MultiByteToWideChar или полезные макросы A2W (ссылка пример ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...