Android JNI-将jstring转换为wchar_t的可靠方法

 2023-01-21    291  

问题描述

在我的Android JNI代码中,我需要将Jstring转换为WCHAR_T.我发现的最接近的参考是如何将JString转换为WCHAR_T *.

可以使用以下代码获得JCHAR*和长度:

Android JNI-将jstring转换为wchar_t的可靠方法

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

wchar_t* wStr = new wchar_t[len+1];

看来我不能使用wcncpy将”原始”复制到” wstr”中.尽管JCHAR长2字,但WCHAR_T在所有现代版本的Android OS上长4个字节.

一个选项是一次在for循环中复制一个字符:

for(int i=0;i<len;i++) {
    wStr[i] = raw[i];
}
wStr[len] = 0;

另一个选项是调用env–> getstringutfchars()并使用iconv_*例程转换为wchar_t type.

有人可以确认选项1是否有效吗?希望我不必求助于选项2.有更好的选择吗?问候.

推荐答案

只要您的所有数据都是UCS2,您就可以使用选项1 .请参阅 wchar_t for linux上的utf-16?/i>进行类似的讨论.请注意,C ++ 11提供 std :: codecvt_utf16 处理情况.

其他推荐答案

wchar_t指定元素大小,而不是字符集或编码.既然您询问32位元素,我们可以假设您要使用Unicode/utf-32吗?无论如何,一旦您决定要使用哪个编码,标准Java库就可以完成任务.

使用 string.getBytes()超载以获取字节数组. (如果您有选择的话,可以在Java而不是JNI中进行此操作.

在Android上,您可能需要Unicode/utf-8.但这具有8位代码单元,因此您可能不会问wchar_t. (UTF-8中的BTW-A字符可能需要1个或更多字节.)

其他推荐答案

一种方法是使用String.getBytes(“UTF-32LE”).请注意,这是假设wchar_t是4个字节和小末端,但这应该是一个相当安全的假设.

这是一个将字符串从Java传递到C ++的示例,将其转换为STD :: WSTRING,反转并传递回Java:

class MyClass {
    private native byte[] reverseString(byte[] arr);
    String reverseString(String s) {
        try {
            return new String(reverseString(s.getBytes("UTF-32")), "UTF-32");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "";
        }
    }
}

在C ++方面,您有:

std::wstring toWStr(JNIEnv *env, jbyteArray s)
{
    const wchar_t *buf = (wchar_t*) env->GetByteArrayElements(s, NULL);
    int n = env->GetArrayLength(s) / sizeof(wchar_t);

    // First byte is BOM (0xfeff), so we skip it, hence the "buf + 1".
    // There IS NO null-terminator.
    std::wstring ret(buf + 1, buf + n);

    env->ReleaseByteArrayElements(s, (jbyte*) buf, 0);
    return ret;
}

jbyteArray fromWStr(JNIEnv *env, const std::wstring &s)
{
    jbyteArray ret = env->NewByteArray((s.size()+1)*sizeof(wchar_t));

    // Add the BOM in front.
    wchar_t bom = 0xfeff;
    env->SetByteArrayRegion(ret, 0, sizeof(wchar_t), (const jbyte*) &bom);

    env->SetByteArrayRegion(ret, sizeof(wchar_t), s.size()*sizeof(wchar_t), (const jbyte*) s.c_str());
    return ret;
}

extern "C" JNIEXPORT jbyteArray JNICALL Java_MyClass_reverseString(JNIEnv *env, jobject thiz, jbyteArray arr)
{
    std::wstring s= toWStr(env, arr);
    std::reverse(s.begin(), s.end());
    return fromWStr(env, s);
}

我在手机上测试了它,该手机具有Android 4.1.2和ARM CPU,以及Android Emulator -Android 4.4.2和X86 CPU,以及此代码:

MyClass obj = new MyClass();
Log.d("test", obj.reverseString("hello, здравствуйте, 您好, こんにちは"));

给出了此输出:

06-04 17:18:20.605: D/test(8285): はちにんこ ,好您 ,етйувтсвардз ,olleh

以上所述是小编给大家介绍的Android JNI-将jstring转换为wchar_t的可靠方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/26319.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。