问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何解决jni char转化为jstring乱码问题

发布网友 发布时间:2022-04-22 09:25

我来回答

1个回答

热心网友 时间:2023-10-26 19:55

java内部是使用16bit的unicode编码(UTF-16)来表示字符串的,无论中文英文都是2字节; jni内部是使用UTF-8编码来表示字符串的,UTF-8是变长编码的unicode,一般ascii字符是1字节,中文是3字节; c/c++使用的是原始数据,ascii就是一个字节了,中文一般是GB2312编码,用两个字节来表示一个汉字。
明确了概念,操作就比较清楚了。下面根据字符流的方向来分别说明一下
1、java --> c/c++
这种情况中,java调用的时候使用的是UTF-16编码的字符串,jvm把这个字符串传给jni,c/c++得到的输入是jstring,这个时候,可以利用jni提供的两种函数,一个是GetStringUTFChars,这个函数将得到一个UTF-8编码的字符串;另一个是 GetStringChars这个将得到UTF-16编码的字符串。无论那个函数,得到的字符串如果含有中文,都需要进一步转化成GB2312的编码。

2、c/c++ --> java
jni返回给java的字符串,c/c++首先应该负责把这个字符串变成UTF-8或者UTF-16格式,然后通过NewStringUTF或者NewString来把它封装成jstring,返回给java就可以了。
如果字符串中不含中文字符,只是标准的ascii码,那么使用GetStringUTFChars/NewStringUTF就可以搞定了,因为这种情况下,UTF-8编码和ascii编码是一致的,不需要转换。
但是如果字符串中有中文字符,那么在c/c++部分进行编码转换就是一个必须了。我们需要两个转换函数,一个是把UTF8/16的编码转成GB2312;一个是把GB2312转成UTF8/16。
这里要说明一下:Linux和win32都支持wchar,这个事实上就是宽度为16bit的unicode编码UTF16,所以,如果我们的 c/c++程序中完全使用wchar类型,那么理论上是不需要这种转换的。但是实际上,我们不可能完全用wchar来取代char的,所以就目前大多数应用而言,转换仍然是必须的。

二、一种转换方法
使用wide char类型来转换。
char* jstringToWindows( JNIEnv *env, jstring jstr )
{ //UTF8/16转换成gb2312
int length = (env)->GetStringLength(jstr );
const jchar* jcstr = (env)->GetStringChars(jstr, 0 );
char* rtn = (char*)malloc( length*2+1 );
int size = 0;
size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );
if( size <= 0 )
return NULL;
(env)->ReleaseStringChars(jstr, jcstr );
rtn[size] = 0;
return rtn;
}

jstring WindowsTojstring( JNIEnv* env, const char* str )
{//gb2312转换成utf8/16
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 );
}
if( buffer )
free( buffer );
return rtn;
}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
浙江有哪些三加二的学校 浙江公办3+2专科学校排名 老师们给看看柿子叶子什么病 51漫画vip兑换码 怎样获得51漫画vip兑换码? 51兑换码怎么用 哪个漫画软件好用一些啊,求推荐。 十万平米的楼房地暖管要用多少 物业管理条例里面有写的,10万平米以下,按建筑面积的千份之四计算,超过... 二级建造师十万平米怎么理解 索尼75寸液晶电视机4k看有线电视会清晰吗 调用Java存储过程遇到SQL4306N时怎么办 在java中若要使用一个包中的类时,首先要求对该包进行导入,其关键字 四大名著分别是什么小说 JNI的误差传递大的数组java C问题,怎么解决 你心目中武侠小说的“四大名著”是什么? 鼠标一动不动 java version &quot;1.7.0_45&quot;报错 四大名著中有哪些(搞笑)穿帮镜头? rocksdb需要引入哪些jar包 rocksdbjni-5.7.3.jar 如何用java测试leveldb代码 税务注销 注销地税税务登记证要到哪里去? 怎么弄个微信分身 注销营业执照去哪里注销? 税务证注销办理 404 Not Found 四大名著有哪几本? 税务注销的流程? 办理税务注销需要提供哪些材料 具体流程是什么 软件包com.ice.jni.registry不存在(java编程) leveldbjni-all组件区分执行机架构吗 请问是什么 索尼4K电视剧几K的 为什么电风扇转动时会发出声音,是因为空气震动么? 电风扇转动会很响什么原因? 电脑上在哪可以看到2k或4k分辨率的电影跟电视剧? 涓什么意思?近义词和反义词是什么?英文翻译是什么? 全国商场业绩200强揭榜 你家乡哪些上榜 老旧商场如何进行业态调整 为什么转动的电风扇会比不转的轻? 热闹的商场200字_作文大全 404 Not Found 商店200字作文 上海最出名的小吃是什么? 商场每满200元减50元,妈妈买衣服实际上花了400元,原来这件衣服多少钱? 什么情况下那转动的电风扇没有风出来? 怎么做饼才好吃 商场 200抵400