源: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

最新文章

  1. “.Net 社区虚拟大会”(dotnetConf) 2016 Day 3 Keynote: Scott Hanselman
  2. hdu 4291 2012成都赛区网络赛 矩阵快速幂 ***
  3. SVN----------项目服务器上的svn客户端自动更新设置。
  4. Ubuntu下为Firefox安装Adobe Flash Player
  5. linux第2天 信号 wait
  6. ArrayList和LinkedList遍历方式及性能对比分析
  7. ASP.NET Web Forms的改进
  8. MySqlCommand, MySqlParameter and "LIKE" with Percent Symbol
  9. sql server varchar(10)和 nvarchar(10)存储数据长度
  10. 更改 android realtek的系统权限
  11. javascript数组的常用方法总结
  12. STM32 - SYSTICK(系统滴答定时器)
  13. CWMP开源代码研究6——libcwmp动态库开发
  14. VUE工程上线首页加载慢问题优化
  15. Android 音视频深入 三 MP4解码播放视频 (附源码下载)
  16. 【转】Swift 语言的设计错误
  17. html5 video,audio控制播放多次,请求/监测全屏状态
  18. 洛谷 Sorting a Three-Valued Sequence 三值的排序
  19. sqlserver 并发机制
  20. ES6数组去重及ES5数组去重方法

热门文章

  1. 介绍两个Android不常用的Drawable:GradientDrawable和 StateListDrawable
  2. Django - 模型表单(创建、更新、删除)
  3. STM32F4xx FPU的设置
  4. [JAR包] android引入JAR包,打包成JAR包,打包成Library项目,导入Library项目
  5. JavaBean,List,Map转成json格式
  6. 【spring boot】SpringBoot初学(2) - properties配置和读取
  7. GridView规则显示图片
  8. ViewPager滑动标签-PagerSlidingTabStrip的使用
  9. 用MyEclipse自动生成hibernate映射文件和实体类
  10. 不停止MySQL服务增加从库的两种方式【转载】