java 如何将 jstring 转换为 wchar_t *

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/68042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:56:14  来源:igfitidea点击:

How do I convert jstring to wchar_t *

javac++java-native-interface

提问by gergonzalez

Let's say that on the C++ side my function takes a variable of type jstringnamed myString. I can convert it to an ANSI string as follows:

假设在 C++ 方面,我的函数采用jstring名为myString. 我可以将其转换为 ANSI 字符串,如下所示:

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

is there a way of getting

有没有办法得到

const wchar_t* unicodeString =...

const wchar_t* unicodeString =...

回答by gergonzalez

If this helps someone... I've used this function for an Android project:

如果这对某人有帮助...我已将此功能用于 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;
}

An improved solution could be (Thanks for the feedback):

改进的解决方案可能是(感谢您的反馈):

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;
}

回答by Andreas Rieder

And who frees wsz? I would recommend STL!

谁释放了 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;
}

回答by Chris Jester-Young

A portable and robust solution is to use iconv, with the understanding that you have to know what encoding your system wchar_tuses (UTF-16 on Windows, UTF-32 on many Unix systems, for example).

一个可移植且健壮的解决方案是使用iconv,并了解您必须知道您的系统wchar_t使用什么编码(例如,Windows 上的 UTF-16,许多 Unix 系统上的 UTF-32)。

If you want to minimise your dependency on third-party code, you can also hand-roll your own UTF-8 converter. This is easy if converting to UTF-32, somewhat harder with UTF-16 because you have to handle surrogate pairs too. :-P Also, you must be careful to reject non-shortestforms, or it can open up security bugs in some cases.

如果您想尽量减少对第三方代码的依赖,您还可以手动滚动您自己的 UTF-8 转换器。如果转换为 UTF-32,这很容易,而使用 UTF-16 则有点困难,因为您也必须处理代理对。:-P 此外,您必须小心拒绝非最短形式,否则在某些情况下可能会打开安全漏洞。

回答by Adam Mitz

JNI has a GetStringChars() function as well. The return type is const jchar*, jchar is 16-bit on win32 so in a way that would be compatible with wchar_t. Not sure if it's real UTF-16 or something else...

JNI 也有一个 GetStringChars() 函数。返回类型是 const jchar*,jchar 在 win32 上是 16 位的,所以在某种程度上与 wchar_t 兼容。不确定它是真正的 UTF-16 还是其他东西......

回答by Benj

I know this was asked a year ago, but I don't like the other answers so I'm going to answer anyway. Here's how we do it in our source:

我知道这是一年前问的,但我不喜欢其他答案,所以我还是要回答。以下是我们在源代码中的做法:

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;
}

EDIT: This solution works well on platforms where wchar_t is 2 bytes, some platforms have a 4 byte wchar_t in which case this solution will not work.

编辑:此解决方案在 wchar_t 为 2 字节的平台上运行良好,某些平台具有 4 字节 wchar_t 在这种情况下此解决方案将不起作用。

回答by Benj

Just use env->GetStringChars(myString, 0); Java pass Unicode by it's nature

只需使用 env->GetStringChars(myString, 0); Java 本质上通过 Unicode

回答by 1800 INFORMATION

If we are not interested in cross platform-ability, in windows you can use the MultiByteToWideChar function, or the helpful macros A2W (ref. example).

如果我们对跨平台能力不感兴趣,在 Windows 中您可以使用 MultiByteToWideChar 函数,或有用的宏 A2W(参考示例)。

回答by Vladimir Ivanov

Rather simple. But do not forget to free the memory by ReleaseStringChars

相当简单。但是不要忘记通过 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);
}

回答by shizhen wang

I try to jstring->char->wchar_t

我尝试 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;
}

回答by Eng.Fouad

Here is how I converted jstringto LPWSTR.

这是我如何转换jstringLPWSTR.

const char* nativeString = env->GetStringUTFChars(javaString, 0);
size_t size = strlen(nativeString) + 1;
LPWSTR lpwstr = new wchar_t[size];
size_t outSize;
mbstowcs_s(&outSize, lpwstr, size, nativeString, size - 1);