Android JNI 由GetStringUTFChars引起的问题

来源:互联网 发布:阿里云免费体验邀请码 编辑:程序博客网 时间:2024/05/01 17:11

java的jni 为Java和c/c++语言间的通信提供了统一的接口。在两种语言的字符串转换方面,我搜了搜,发现很多都是人云亦云。如果不是因为做项目遇到遗留的bug,恐怕我也人云亦云了。

先看一下 jchar的定义

typedef unsigned short  jchar;          /* unsigned 16 bits */

 是一个无符号端整型,而不是wchar_t。(参考jni.h,这文件在Android NDK里面,搜索就能找到)

为了兼容早期的jvm ,java使用16比特(两字节)表示一个小于65535的UNICODE码,用代理对的形式表示其他UNICODE码(关于代理对,http://zh.wikipedia.org/zh-cn/UTF-16)

而将UNICODE编码时,若使用变种UTF8,java会把字节 00  变为 0xC0 80,编码代理对更复杂(http://zh.wikipedia.org/wiki/UTF-8)。

好了,有了以上的认识,在使用JNI的一些接口时就要注意了

 

jstring  到 c/c++字符串

应从 jchar 到 wchar_t  的转换,而不是jchar  到 char。也就是在转换时,要保持jstring的每个jchar的值不变。

JNIEnv *env = 获取相关句柄;jstring jstr = java字符串;//获取java字符串的长度jsize jstr_len = env->GetStringLength(jstr);//获取java字符串的jchar指针const jchar * pjstr = env->GetStringChars(jstr);//申请c字符串的内存空间wchar_t *pcstr = new wchar_t[jstr_len];//通常 sizeof(wchar_t)不小于2,若为1,应考虑使用其他类型来容纳jchar//或者std::wstring wstr;wstr.assign(jstr_len,0);//复制jstr_len --;while( jstr_len > -1 ){    pcstr[jstr_len ] = pjstr[jstr_len];    //或者     wstr[jstr_len] = pjstr[jstr_len];    jstr_len -- ;}

上面代码使用了GetStringChars而不是GetStringUTFChars。之所以这样做,就是为了保持java字符串到c/c++字符串的无损转换。

不过,仍然要注意一个问题,就00字节的处理,建议使用c++的wstring类。

 

如果:

        1、jstring的每一个jchar都在[1,127]内

        2、或者,你需要做UTF8转换但是不关心GetStringUTFChars采用变种UTF8还是标准UTF8,也不关心可逆转换

可以使用GetStringUTFChars。

原创粉丝点击