JNI 中文字符串传递(转)
因为项目编码中通过JNI传递中文字符时出现乱码问题,特搜集了相关资料,整理如下:
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的编码。
在C++编写的DLL文件中添加如下转换函数:
char * JStringToCharArray(JNIEnv * pJNIEnv, jstring jstr)
{
jsize len = pJNIEnv->GetStringLength( jstr );
const jchar * jcstr = pJNIEnv->GetStringChars( jstr, NULL ); int size = ;
char * str = ( char * )malloc( len * + );
if ( (size = WideCharToMultiByte( CP_ACP, , LPCWSTR( jcstr ), len, str, len * + , NULL, NULL ) ) == )
return NULL; pJNIEnv->ReleaseStringChars( jstr, jcstr ); str[ size ] = ;
return str;
}
假设DLL中以下这个函数接受到JAVA传递的带有中文的字符串jMsg,处理如下:
JNIEXPORT void JNICALL Java_Test_hello(JNIEnv * env, jclass obj, jstring jMsg)
{
//若使用const char *strMsgPtr = env->GetStringUTFChars( jMsg , 0)则会出错
char * strMsgPtr = JStringToCharArray( env, jMsg ); //使用上面提供的转换函数接收字符串 /*
接下来便可使用strMsgPtr做你所需要的处理
*/
}
2、c/c++ --> java
jni返回给java的字符串,c/c++首先应该负责把这个字符串变成UTF-8或者UTF-16格式,然后通过NewStringUTF或者NewString来把它封装成jstring,返回给java就可以了。
如果字符串中不含中文字符,只是标准的ascii码,那么用GetStringUTFChars/NewStringUTF就可以搞定了,因为这种情况下,UTF-8编码和ascii编码是一致的,不需要转
但是如果字符串中有中文字符,那么在c/c++部分进行编码转换就是一个必须了。
转载自: http://hi.baidu.com/ivy_jing/blog/item/1a2d90899712f119c8fc7a29.html
最新文章
- “.Net 社区虚拟大会”(dotnetConf) 2016 Day 3 Keynote: Scott Hanselman
- hdu 4291 2012成都赛区网络赛 矩阵快速幂 ***
- SVN----------项目服务器上的svn客户端自动更新设置。
- Ubuntu下为Firefox安装Adobe Flash Player
- linux第2天 信号 wait
- ArrayList和LinkedList遍历方式及性能对比分析
- ASP.NET Web Forms的改进
- MySqlCommand, MySqlParameter and ";LIKE"; with Percent Symbol
- sql server varchar(10)和 nvarchar(10)存储数据长度
- 更改 android realtek的系统权限
- javascript数组的常用方法总结
- STM32 - SYSTICK(系统滴答定时器)
- CWMP开源代码研究6——libcwmp动态库开发
- VUE工程上线首页加载慢问题优化
- Android 音视频深入 三 MP4解码播放视频 (附源码下载)
- 【转】Swift 语言的设计错误
- html5 video,audio控制播放多次,请求/监测全屏状态
- 洛谷 Sorting a Three-Valued Sequence 三值的排序
- sqlserver 并发机制
- ES6数组去重及ES5数组去重方法
热门文章
- 介绍两个Android不常用的Drawable:GradientDrawable和 StateListDrawable
- Django - 模型表单(创建、更新、删除)
- STM32F4xx FPU的设置
- [JAR包] android引入JAR包,打包成JAR包,打包成Library项目,导入Library项目
- JavaBean,List,Map转成json格式
- 【spring boot】SpringBoot初学(2) - properties配置和读取
- GridView规则显示图片
- ViewPager滑动标签-PagerSlidingTabStrip的使用
- 用MyEclipse自动生成hibernate映射文件和实体类
- 不停止MySQL服务增加从库的两种方式【转载】