您的位置:首页 > 其它

JNI 中文字符串传递

2013-11-22 15:36 1376 查看
因为项目编码中通过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 = 0;
char * str = ( char * )malloc( len * 2 + 1 );
if ( (size = WideCharToMultiByte( CP_ACP, 0, LPCWSTR( jcstr ), len, str, len * 2 + 1, NULL, NULL ) ) == 0 )
return NULL;

pJNIEnv->ReleaseStringChars( jstr, jcstr );

str[ size ] = 0;
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
阅读(1258) | 评论(0) | 转发(0) |

0
上一篇:LINUX下GDB调试(转)

下一篇:VIM 用空格替换 Tab

相关热门文章

linux 常见服务端口

【ROOTFS搭建】busybox的httpd...

什么是shell

linux socket的bug??

linux的线程是否受到了保护?...

修改默认端口为222,centos自...

用PHP做一个ftp登录页面...

Toad for Oracle工具,为什么在...

本地win7安装vmw9系统winserv...

powermt config是所什么用的...

给主人留下些什么吧!~~

评论热议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: