关于Java:如何将jstring转换为wchar_t *

关于Java:如何将jstring转换为wchar_t *

How do I convert jstring to wchar_t *

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

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

有没有办法

const wchar_t* unicodeString = ...


如果这对某人有帮助...我已将此功能用于Android项目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}

谁释放了wsz?
我会推荐STL!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}


JNI也具有GetStringChars()函数。返回类型为const jchar *,在Win32上jchar为16位,因此与wchar_t兼容。不知道这是真正的UTF-16还是其他东西...


一个可移植且强大的解决方案是使用iconv,但要了解您必须知道系统wchar_t使用的编码方式(例如,在Windows上为UTF-16,在许多Unix系统上为UTF-32)。

如果要最大程度地减少对第三方代码的依赖性,还可以手动滚动自己的UTF-8转换器。如果转换为UTF-32很容易,而使用UTF-16则更难,因为您也必须处理代理对。 :-P另外,您必须小心拒绝非最短格式,否则在某些情况下它可能会打开安全错误。


我知道这是一年前提出的,但是我不喜欢其他答案,所以我还是要回答。这是我们在源代码中的处理方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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,在这种情况下此解决方案将不起作用。


这是我将jstring转换为LPWSTR的方法。

1
2
3
4
5
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);

我尝试jstring-> char-> wchar_t

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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;
}

相当简单。但不要忘记通过ReleaseStringChars释放内存

1
2
3
4
5
6
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);
}

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


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


推荐阅读

    excel怎么用乘法函数

    excel怎么用乘法函数,乘法,函数,哪个,excel乘法函数怎么用?1、首先用鼠标选中要计算的单元格。2、然后选中单元格后点击左上方工具栏的fx公

    excel中乘法函数是什么?

    excel中乘法函数是什么?,乘法,函数,什么,打开表格,在C1单元格中输入“=A1*B1”乘法公式。以此类推到多个单元。1、A1*B1=C1的Excel乘法公式

    标准差excel用什么函数?

    标准差excel用什么函数?,函数,标准,什么,在数据单元格的下方输入l标准差公式函数公式“=STDEVPA(C2:C6)”。按下回车,求出标准公差值。详细

    公共CPU接口类型的详细描述

    公共CPU接口类型的详细描述,,我们知道CPU是电脑的大脑, CPU的处理速度直接决定电脑的性能, 那你知道CPU发展到现在, 都那些CPU接口类型吗.

    字符库快捷键|字符串快捷键

    字符库快捷键|字符串快捷键,,1. 字符串快捷键1、单行注释单行注释是 #Mac的快捷键是 command+/windows的快捷键是 Ctrl + /2、多行注

    主板类型百科全书(基于芯片分类)

    主板类型百科全书(基于芯片分类),,电脑维修基础之主板型号熟悉,主板芯片型号区分,涵盖nVIDIA系列intel系列AMD系列主板型号,主板型号大全内容较

    excel常用函数都有哪些?

    excel常用函数都有哪些?,函数,哪些,常用,1、SUM函数:SUM函数的作用是求和。函数公式为=sum()例如:统计一个单元格区域:=sum(A1:A10)  统计多个

    电脑表格转换为图表|表格转换成图表

    电脑表格转换为图表|表格转换成图表,,表格转换成图表1、选择A列,在“插入”选项下的“数据透视表”中,将数据透视字段拖曳到“行”和“值”

    C上的引导检查文件系统:文件的类型

    C上的引导检查文件系统:文件的类型,,故障现象:系统检查启动检查文件 每一次你启动一台计算机,都会是这样的。 在d上检查文件系统: 该文件

    电脑硬盘接|电脑硬盘接口类型怎么看

    电脑硬盘接|电脑硬盘接口类型怎么看,,电脑硬盘接口类型怎么看方法如下:1、在计算机上点击右键,选择设备管理器;2、点开磁盘驱动器就可以看到